RussellHarrower
RussellHarrower

Reputation: 6820

find geo-points inside area

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

Upvotes: 1

Views: 284

Answers (2)

turivishal
turivishal

Reputation: 36134

  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!

Upvotes: 1

Tom Elias
Tom Elias

Reputation: 782

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

Upvotes: 0

Related Questions