MongoDB $geoNear Aggregation on another collection

692 Views Asked by At

I have a database with two collections like so:

[
  {
    "name": "Person A",
    "location": {"type": "Point", "coordinates": [180, 90]}
  },
  {
    "name": "Person B",
    "location": {"type": "Point", "coordinates": [-180, -90]}
  }
]
[
  {
    "name": "Store A",
    "location": {"type": "Point", "coordinates": [180, 90]}
  },
  {
    "name": "Store B",
    "location": {"type": "Point", "coordinates": [-180, -90]}
  }
]

For each person, I want to find the nearest place. I could get it to find the nearest place for one specific pair of coordinates, not for the entire collection. Is there any way to do that without using foreach? This is the closest I got following the MongoDB documentation:

// Current $geoNear:
{
  // Instead of having to give constants of a single
  // point, I want to compare against all coordinates
  // of another collection.              ↓
  near: {"type":"Point","coordinates":[-180, 90]},
  distanceField: 'distance',
  maxDistance: 50,
  spherical: true
}
1

There are 1 best solutions below

2
Hussam On

This can be achieved using aggregation.

[{
$lookup: {
  from: "places",
  let: {
    "personPoint": "$location"
  },
  as: "nearestPlace",
  pipeline: [
    {
      $geoNear: {
        near: "$$personPoint",
        spherical: true,
        distanceField: "distance",
        maxDistance: 50,
        
      }
    },
    {
      $unwind: "$location"
    },
    
  ]
 }
},
{
 $unwind: {
  path: "$nearestPlace",
  preserveNullAndEmptyArrays: true
 }
}]

I couldn't test it on playground because of geo index. So might require some minor fix. If anyone can make it work on playground heres the link https://mongoplayground.net/p/aROX976gYzC


Edit: here is a playground link that have 2dsphere index
playground