1

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
}
Mochi
  • 47
  • 1
  • 8

1 Answers1

1

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

Hussam
  • 1,606
  • 9
  • 20
  • `$$personPoint` is a GeoJSON object, so shouldn't it be `near: "$$personPoint"`? Also, even with this I get an error: `$geoNear requires a 'near' option as an Array` – Mochi Feb 19 '22 at 04:54
  • @Mochi yes you are right. I just realized your location is an object so don't need it. I updated my answer for that. As mentioned I couldn't test it because of playground limitation : ( – Hussam Feb 19 '22 at 21:07