Mongodb aggregate on two collections based on geopoint

Viewed 55

I have two collections

person

{
    "name": "Mike",
    "age": 42,
    "address": {
         "location": {"type": "Point", "coordinates": [12.3456, 78.9101]}
    }
}

restaurant

{
    "name": "Bistro",
    "type": ["Maxican", "Italian"],
    "location": {"type": "Point", "coordinates": [12.3555, 78.9333]} 
}

I've created spherical indexes on both collections

db.person.createIndex({"address.location": "2dsphere"})
db.restaurant.createIndex({"location": "2dsphere"})

Now I want to find all the restaurants near to a person using lat/long in both collections. for e.g find all the restaurants within 10KM of a person. result will look like below

{
    "name": "Mike",
    "age": 42,
    "address": {
         "location": {"type": "Point", "coordinates": [12.3456, 78.9101]}
    },
    "nearby_restaurants": [{"name": "Bistro", "distance": 5.3}]  // this means bistro is 5.3 KM away from this person
}

Notice that, I'm only using name field from restaurant collection and an additional field distance which will be calculated after the query.

I want to do this for all person. so basically for each person, i have to scan the whole restaurant collection every time. To achieve this I thought of using lookup with aggregate, something like below

db.person.aggregate([
    {
        $lookup: {
            from: "restaurant",
            let: {"personPoint": "$address.location"},
            as: "nearby_restaurants",
            pipeline: [
                {
                    $geoNear: {
                        near: "$$personPoint",
                        spherical: true,
                        distanceField: "distance",
                        maxDistance: 10 * 1000,  // within 10 KM
                        distanceMultiplier: 0.001  // get the result in KM
                    }
                },
                {
                    $unwind: "$location"
                },
            ]
        }
    }, 
    {
        $unwind: {
            path: "$nearby_restaurants",
            preserveNullAndEmptyArrays: true
        }
    }
])

This doesnt work at all. I get this error: $geoNear requires a 'near' option as an Array"

I tried to look at different sources but couldnt understand and fix the error.

PS: If currently, it's not possible through lookups/aggregate, how can we achieve the same through looping over each person's document?

0 Answers
Related