aruuuuu
aruuuuu

Reputation: 1645

MongoDB: Using $geoIntersects or $geoWithin with $near in one query

I would like to query for all documents that have a polygon that a point is contained in and then for that result set, order it based on closeness of that point to the location of the document.

So imagine I have a database of friends because I'm just that cool, and would like to see which friends are within the my range and would be willing to come play. (each friend has a play-date polygon which is the range they are willing to travel for a play-date)

For all matches I would like to them proceed to see which friend I should call to come based on his actual address and its distance to my point (which is my address) so that I can determine if I am ok with them coming from far away. (lets say 300 meters)

So far I have below a query to find polygons that my point is contained within but I do not know how to include the $near operator of mongodb

For JSON:

{
    "_id" : "objid",
    "FRIEND_NAME" : "Bobby",
    "GEOMETRY" : {
        "type":"Polygon",
        "coordinates":[[
            [-73.98779153823898,40.718233223261],
            [-74.004946447098,40.723575517498],
            [-74.006771211624,40.730592217474],
            [-73.99010896682698,40.746712376146],
            [-73.973135948181,40.73974615047701],
            [-73.975120782852,40.736128627654],
            [-73.973997695541,40.730787341083],
            [-73.983317613602,40.716639396436],
            [-73.98779153823898,40.718233223261]
    ]]},
    "FRIEND_POSITON" : {"lon" : -73.992188, "lat" : 40.729359 }
}

This works:

db.friends.find({
  "PLAYDATE_RANGE":{
    "$geoIntersects":{
      "$geometry":{
        "type":"Point",
        "coordinates":[-73.98652, 40.752044]
      }
    }
  }
})

This does not:

db.friends.find([
  {
    "PLAYDATE_RANGE":{
      "$geoIntersects":{
        "$geometry":{
          "type":"Point",
          "coordinates":[-73.98652, 40.752044]
        }
      }
    }
  },
  {
    "FRIEND_POSITON":{
      "$geoNear":{
        "near":{
          "type":"Point",
          "coordinates": [-73.98652, 40.752044]
        },
        "maxDistance":300
      } 
    }
  }
])

Please help me with the query above that does not work.

Upvotes: 4

Views: 2561

Answers (1)

aruuuuu
aruuuuu

Reputation: 1645

This requires an aggregate pipeline. As per mogodb doc for $geoNear, You can only use $geoNear as the first stage of a pipeline. The aggregate function has an entry for an additional query which is where the polygon query will be used to narraw down results based on inclusion in the PLAYDATE_RANGE field of the document.

db.friends.aggregate([
    {
        $geoNear: {
            near: { type: "Point", coordinates: [-73.98652, 40.752044] },
            maxDistance: 300,
            distanceField: "friends.calculated_distance",
            query: {
                "PLAYDATE_RANGE": {
                    "$geoIntersects": {
                        "$geometry": {
                            "type": "Point",
                            "coordinates":[-73.98652, 40.752044]
                        }
                    }
                }
            },
            spherical: true
        }
    }
])

P.S. note that only one geospatial index can be used so put it on the FRIEND_POSITION field. If adding a 2sphere index that requires a correctly formed GeoJSON value, specifically,

"FRIEND_POSITION" : { "type" : "Point", "coordinates" : [ -73.992188, 40.729359 ] }

So the document should look like:

{
  "_id" : "objid",
  "FRIEND_NAME" : "Bobby",
  "GEOMETRY" : {
    "type": "Polygon",
    "coordinates":[[
      [-73.98779153823898,40.718233223261],
      [-74.004946447098,40.723575517498],
      [-74.006771211624,40.730592217474],
      [-73.99010896682698,40.746712376146,
      [-73.973135948181,40.73974615047701],
      [-73.975120782852,40.736128627654],
      [-73.973997695541,40.730787341083],
      [-73.983317613602,40.716639396436],
      [-73.98779153823898,40.718233223261]
  ]]},
  "FRIEND_POSITION" : {
    "type" : "Point",
    "coordinates" : [ -73.992188, 40.729359 ]
  }
}

Upvotes: 3

Related Questions