skip to Main Content

I’m making an aggregation and making 3 $lookup in 3 differents collections to get a collection where the location is .

The problem is : I cant do a $geoNear after the first stage of the pipeline. So I tried $nearSphere at the end of pipeline but it didn’t work.

Any other way ?
If I could get the distance I could sort the array after the aggregation.

The only solution I found, is : after the aggregation, I calculate the distance from the same point for each document and sort them but I’m not sure sure it is the most optimized !

Here is the aggregation I tried:

MyCollection.aggregate([
  {
    $match: {
      job: 'professor'
    }
  },
  {
    $lookup: {
      from: "otherCollection",
      localField: "_id",
      foreignField: "_id",
      as: "otherCollection"
    }
  },
  {
    $unwind: {
      path: "otherCollection",
      "preserveNullAndEmptyArrays": true
    }
  },
  {
    $addFields: {
      location: '$otherCollection.location'
    }
  },
  {
    $nearSphere: {
      $geometry: {
        type: "Point",
        coordinates: [lng, lat] // Those avriables are passed in arguments in the function before
      },
      $maxDistance: radius * 1000,
      // I tried to add a $key field to get $otherCollection._id but it doesn't worked
    }

  }
], function(err, data) {
  if (err) errorCbk(err)

  successCbk(data)
});

Thanks.

2

Answers


  1. You can use $sort and make any calculation you want on it https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort/

    Login or Signup to reply.
  2. You could "invert" the query by first using "$geoNear" in otherCollection and then "$lookup" into MyCollection.

    Something like this.

    db.otherCollection.aggregate([
      {
        "$geoNear": {
          "near": {
            "type": "Point",
            "coordinates": [ -46.0, -68.0 ]
          },
          "maxDistance": 2000000,
          "distanceField": "dist.calculated"
        }
      },
      {
        "$lookup": {
          "from": "MyCollection",
          "localField": "_id",
          "foreignField": "_id",
          "pipeline": [
            { "$match": { "job": "professor" } }
          ],
          "as": "nearProfs"
        }
      },
      {
        "$match": {
          "$expr": {
            "$gt": [ { "$size": "$nearProfs" }, 0 ]
          }
        }
      }
    ])
    

    Try it with fake data on mongoplayground.net.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search