I'm basing my code from this example to perform a lookup (left join) then a geoNear.
db.jobs.aggregate([
{
"$lookup": {
"from": "companies",
"localField": "company",
"foreignField": "_id",
"as": "company",
"pipeline": [
{
"$geoNear": {
"near": {
"type": "Point",
"coordinates": [
-80,
44
],
},
"key": "company.geo",
"distanceField": "distance"
}
}
]
}
}
])
I've created a mongo playground
I'm getting the error
$geoNear is only valid as the first stage in an optimized pipeline
How do I perform a geoNear in a lookup pipeline? Removing the pipeline shows the joined document.
CodePudding user response:
The root cause is that you used a concise syntax for $lookup
. From the official document,
The new concise syntax removes the requirement for an equality match on the foreign and local fields inside of an $expr operator in a $match stage.
So the matching between localField
and foreignField
is treated as the first stage of the sub-pipeline.
Solution: You can simply move the clause to another $match
stage after $geoNear
db.jobs.aggregate([
{
"$lookup": {
"from": "companies",
"let": {
company: "$company"
},
"as": "company",
"pipeline": [
{
"$geoNear": {
"near": {
"type": "Point",
"coordinates": [
-80,
44
],
},
"key": "company.geo",
"distanceField": "distance"
}
},
{
$match: {
$expr: {
$eq: [
"$_id",
"$$company"
]
}
}
}
]
}
}
])
Mongo Playground seems cannot demonstrate the behaviour for this case since it involves the usage of 2d-index. But I put it here nevertheless.