1

In my lootPoint collection I have the data like this:

{
    "_id" : "1856132932",
    "point" : {
        "type" : "Point",
        "coordinates" : [ 
            21.6550408, 
            50.1034841
        ]
    }
}

{
    "_id" : "2184534902",
    "point" : {
        "type" : "Point",
        "coordinates" : [ 
            21.6560194, 
            50.1037961
        ]
    }
}

I want to query for a random point, matching the square with the circular 20m cut-out in the middle:

enter image description here

Using Internet and AI I managed to assemble the following:

db.lootPoint.aggregate([
  {
    $match: {
      "point.coordinates": {
        $geoWithin: {
          $geometry: {
            type: "Polygon",
            coordinates: [
              [
                  [21.654939727403415,50.10333291665514],
                  [21.656736672596585,50.10333291665514],
                  [21.656736672596585,50.10453288334485],
                  [21.654939727403415,50.10453288334485],
                  [21.654939727403415,50.10333291665514]
              ]
            ]
          }
        },
        $not: {
          $geoWithin: {
            $centerSphere: [[21.6558382, 50.1039329], 20 / 3963.2]
          }
        }
      }
    }
  },
  { $sample: { size: 1 } }
])

Upon running this command in Robo3T I'm getting the error: can't parse field $not...

I tried re-writing the query like with $and and $not so:

db.lootPoint.aggregate([
  {
    $match: {
      $and:[
        { "point.coordinates": {...} },
        { "point.coordinates": { $not:[ ... ] } },
      ]
    }
  },
  ...

but it brings up 0 results.

What am I doing wrong? How to make this query valid? Are there any alternative approaches?

2
  • mongoplayground.net/p/Uv5JOz8vfcb maybe your radian calculation has issues. 3963.2 is for miles. for km 6378.1 or divide by 6378100 for m
    – cmgchess
    Commented Jul 4 at 18:03
  • @cmgchess yeah, 20 is also kinda too much for 20 m distance, and should be 0.02. Feel free to post your sample as an answer!
    – injecteer
    Commented Jul 4 at 21:03

1 Answer 1

1

Your query with $and looks correct. The problem might be that your meters to radian conversion might be wrong

According to the docs dividing by 3963.2 is for converting miles to radians. Similarly the docs also state that to covert km to radians you have to divide by 6378.1. So to convert meters to radians have to divide by 6378100

db.collection.aggregate([
  {
    $match: {
      $and: [
        {
          "point.coordinates": {
            $geoWithin: {
              $geometry: {
                type: "Polygon",
                coordinates: [[
                  [21.654939727403415, 50.10333291665514],
                  [21.656736672596585, 50.10333291665514],
                  [21.656736672596585, 50.10453288334485],
                  [21.654939727403415, 50.10453288334485],
                  [21.654939727403415, 50.10333291665514]
                ]]
              }
            }
          }
        },
        {
          "point.coordinates": {
            $not: {
              $geoWithin: {
                $centerSphere: [
                  [21.6558382, 50.1039329],
                  0.0000031357300763550272 // 0.02/6378.1 for km to radians
                ]
              }
            }
          }
        }
      ]
    }
  }
])

https://mongoplayground.net/p/Uv5JOz8vfcb

Not the answer you're looking for? Browse other questions tagged or ask your own question.