find geo-points inside area

Viewed 147

how can I search for all geopoints inside an area in mongodb.

My collection has

{
    "_id": {
        "$oid": "5fa2a64d267b8309fe781d98"
    },
    "location": {
        "coordinates": ["115.880453987155", "-31.925513609342207"]
    }
}

And I want to now search this data to see if a user is inside

top: -31.97127, 115.98367 Bottom: -32.11739, 115.85955

are we need to search

I have tried to run

[
  {
    '$search': {
      'location': {
        '$geoWithin': {
          '$geometry': {
            'type': 'Polygon', 
            'coordinates': [
              [
                115.8455154208042, -31.97458396927722
              ], [
                115.8830653531429, -31.97460201459856
              ], [
                115.8823782261087, -31.94124526669114
              ], [
                115.8498438592383, -31.9409449398814
              ], [
                115.8455154208042, -31.97458396927722
              ]
            ], 
            'crs': {
              'type': 'name', 
              'properties': {
                'name': 'urn:x-mongodb:crs:strictwinding:EPSG:4326'
              }
            }
          }
        }
      }
    }
  }
]

But get error Remote error from mongot :: caused by :: Query should contain either operator or collector

https://mongoplayground.net/p/xwRyKoEXlBI

2 Answers
  1. First of all you need to change the type of the coordinate from string to number in your collection, see the GeoJSON Objects examples,
{
    "_id": {
        "$oid": "5fa2a64d267b8309fe781d98"
    },
    "location": {
        "coordinates": [115.880453987155, -31.925513609342207]
    }
}
  • You can try an update query:
  • $arrayElemAt to get specific element from array
  • $toDouble to convert value to double
db.collection.updateMany(
  { "location.coordinates": { $exists: true } },
  [{
    $set: {
      "location.coordinates": [
        { 
          $toDouble: {
            $arrayElemAt: ["$location.coordinates", 0]
          }
        },
        { 
          $toDouble: {
            $arrayElemAt: ["$location.coordinates", 1]
          }
        }
      ]
    }
  }]
)
  1. Create a 2dsphere index:
    • A geospatial index, and almost always improves performance of $geoWithin and $geoIntersects queries.
db.collection.createIndex({ location: "2dsphere" })
  1. Correct your query:
db.collection.find({ 
  location: { 
    $geoWithin: { 
      $geometry: {
        "type" : "Polygon",
        "coordinates" : [
          [
            [115.8455154208042, -31.97458396927722],
            [115.8830653531429, -31.97460201459856],
            [115.8823782261087, -31.94124526669114],
            [115.8498438592383, -31.9409449398814],
            [115.8455154208042, -31.97458396927722]
          ]
        ]
      } 
    } 
  } 
})

I have not tested all the flow, make sure you should clone your database and do this kind of testing in the testing collection!

if you could extract geometry points from your map to form a "polygon", then you could search your point inside it with a $geoWithin search: GeoWithin search

Related