MongoDB can't parse query (2dsphere): two conditions

Viewed 58

I have the following object in my Collection:

{
   "_id":"test123",
   "footprint":{
      "type":"Polygon",
      "coordinates":[
         [
            [10, 30], [20, 45], [38, 38], [43, 38], [45, 30], [10, 30]
         ]
      ]
   }
}

with index of type "2dsphere" on "footprint" attribute.

Now, I would like to implements the geospatial query "overlaps", as implemented by ST_Overlaps in PostGIS: https://postgis.net/docs/ST_Overlaps.html.

Due to the fact that MongoDB doesn't support "overlap" natively (only within, intersect and near) and according to the above definition, I whould return all overlapping documents not totally within the search area.

Therefore, I'm trying to execute the following filter:

{
   "footprint":{
      "$geoIntersects":{
         "$geometry":{
            "type":"Polygon",
            "coordinates":[
               [
                  [
                     41.62109375000001,
                     38.087716380862716
                  ],
                  [
                     41.870727539062514,
                     37.998201197578084
                  ],
                  [
                     41.72393798828124,
                     38.01268326428104
                  ],
                  [
                     41.62109375000001,
                     38.087716380862716
                  ]
               ]
            ]
         }
      },
      "$not":{
         "$geoWithin":{
            "$geometry":{
               "type":"Polygon",
               "coordinates":[
                  [
                     [
                        41.62109375000001,
                        38.087716380862716
                     ],
                     [
                        41.870727539062514,
                        37.998201197578084
                     ],
                     [
                        41.72393798828124,
                        38.01268326428104
                     ],
                     [
                        41.62109375000001,
                        38.087716380862716
                     ]
                  ]
               ]
            }
         }
      }
   }
}

But I get the following error:

can't parse extra field: $not: { $geoWithin: { $geometry: { type: "Polygon", coordinates: [ [ [ 41.62109375000001, 38.08771638086272 ], [ 41.87072753906251, 37.99820119757808 ], [ 41.72393798828124, 38.01268326428104 ], [ 41.62109375000001, 38.08771638086272 ] ] ] } } }

After several tests, it seems I can't execute a second filter on the same attribute.

Am I wrong? Is there any workaround?

Thanks

1 Answers

This is due to the query language and how it parses objects, the object you're trying to use looks like this:

{ key: { query1, query2 }}

Where query1 is $geoIntersects and query2 is $not which is just not a valid structure, what you can do is wrap both of them with an $and query like so:

{
    $and: [
        {
            "footprint": {
                "$geoIntersects": {
                    "$geometry": {
                        "type": "Polygon",
                        "coordinates": [
                            [
                                [
                                    41.62109375000001,
                                    38.087716380862716
                                ],
                                [
                                    41.870727539062514,
                                    37.998201197578084
                                ],
                                [
                                    41.72393798828124,
                                    38.01268326428104
                                ],
                                [
                                    41.62109375000001,
                                    38.087716380862716
                                ]
                            ]
                        ]
                    }
                }
            }
        },
        {
            footprint: {
                "$not": {
                    "$geoWithin": {
                        "$geometry": {
                            "type": "Polygon",
                            "coordinates": [
                                [
                                    [
                                        41.62109375000001,
                                        38.087716380862716
                                    ],
                                    [
                                        41.870727539062514,
                                        37.998201197578084
                                    ],
                                    [
                                        41.72393798828124,
                                        38.01268326428104
                                    ],
                                    [
                                        41.62109375000001,
                                        38.087716380862716
                                    ]
                                ]
                            ]
                        }
                    }
                }
            }
        }
    ]
}
Related