0

I am not sure if there is a way to do this. I need to have a circle in mongodb and run a query against that with a box using $box to see if these two shapes overlap or not. However, Geojson does not support circles. What would be the best way to get this done? The circle is stored like this:

places = { 
...
"location": {
    "type": "Point",
    "coordinates": [
        -79.390756,
        43.706685
    ]
},
"radius": 100
}

I have two specific problems:

  1. The first issue is that maxDistance is stored in the same object as the Geojson object and cannot be used in a $near query with $maxDistance; it only takes a number.
  2. I do a partial postal code/ zip code search on Google Geocoding Api which returns a box with two corner coordinates like this:

    "geometry": { "bounds": { "northeast": { "lat": 43.710565, "lng": -79.37363479999999 }, "southwest": { "lat": 43.690848, "lng": -79.40025399999999 } } As far as I know,I cannot use $box as it only works with $geoWithin.

Edit 1: My initial plan with the circle and the box changed mainly because I did not find a suitable and efficient solution to this problem. Instead of checking if the circle overlaps with the box, now I check if a Geojson point is inside the circle as follows:

db.places.aggregate([
{"$geoNear": {near: { type: "Point", coordinates: [  -80.459293, 40.713640] }, 
distanceField: "dist.calculated", maxDistance: 100000, 
key: 'myLocation', query: { 'SomeField': "..." }, spherical: true}},
{ "$match" :  {$expr:{ $lte:['$dist.calculated', 'radius']}}}])

The problem here is that I d have to run a query within 100 KM first and then in another stage of the aggregation check the distance. Is there a more efficient way to implement this? Thanks.

BlackLog
  • 301
  • 1
  • 5
  • 17

1 Answers1

0

You can store a circle as point and radius. And you can use a $near query with a point and $maxDistance in meters which is the radius of the circle. See MongoDB Documentation.

https://en.wikipedia.org/wiki/Radius

Query to find all location, geometry field of the collection, at a certain distance from a point.

db.places.find(
   {
     location:
       { $near :
          {
            $geometry: { type: "Point",  coordinates: [ -73.9667, 40.78 ] },
            $maxDistance: 5000
          }
       }
   }
)

Query to find if a given geometry (point, polygon(rect too)) in a query intersects with a geometry of a field in the collection.

//find quests bots that matches the users location
await Collection.find({     geometry:   
  { $geoIntersects: 
   { 
     {
      type: "Point",
      coordinates: [
        -73.99460599999999,
        40.7347229
        ]
      }
    } 
  }                         
});
Stan Wiechers
  • 1,962
  • 27
  • 45
  • Thanks a lot. looks good. I am wondering though if there is a way to use $box ( or something with the same functionality) within the $geometry clause. I use Google Geocode Api for partial postal code lookup and it returns an object with two coordinates like this: "northeast": { "lat": 43.710565, "lng": -79.37363479999999 }, "southwest": { "lat": 43.690848, "lng": -79.40025399999999 }. Is there a way to create a box out of these two coordinates, and check if it overlaps with the circle? Thanks. – BlackLog Dec 27 '19 at 02:42
  • Of course, you can create a box out the bounding box out of that. [NE, NW, SW, SE] – Stan Wiechers Dec 27 '19 at 03:26
  • I meant using mongdb to create the bounding box with two corner coordinates... – BlackLog Dec 27 '19 at 15:40
  • A polygon works: https://docs.mongodb.com/manual/reference/geojson/#polygon . Just make it close the shape by repeating the first point NE. [NE, NW, SW, SE, NE] – Stan Wiechers Dec 27 '19 at 16:05
  • Nice. There is no way to read the maxDistance from the same obejct in the query as far as I know. I might be able to do it via aggregation. Do you have any suggestions for that? – BlackLog Dec 27 '19 at 16:46
  • I added another example. All you is possible, but maybe I am misunderstanding and you should clarify your question and provide examples to better illustrate your undertaking. – Stan Wiechers Dec 27 '19 at 23:39