Home > Enterprise >  MongoDB aggregate geoNear in lookup pipeline not behaving like documentation
MongoDB aggregate geoNear in lookup pipeline not behaving like documentation

Time:11-09

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.

  • Related