Matching points from one collection with polygons from another

I’m trying to match points in one collection with regions stored in another collection.
Here are examples of documents.

Points:

{ 
  "_id" : ObjectId("5e36d904618c0ea59f1eb04f"), 
  "gps" : { "lat" : 50.073288, "lon" : 14.43979 },  
  "timeAdded" : ISODate("2020-02-02T15:13:22.096Z") 
}

Regions:

{
  "_id" : ObjectId("5e49a469afae4a11c4ff3cf7"), 
  "type" : "Feature", 
  "geometry" : { 
    "type" : "Polygon", 
    "coordinates" : [[ 
        [ 14.609644294937652, 50.02081908813608 ],
        [ 14.609640493282695, 50.02078482460302 ],
        [ 14.609603249828798, 50.020776412254065 ],
        [ 14.609548954187744, 50.02072977072492 ],
        ... 
        [ 14.609433408712134, 50.0208718692152 ],
        [ 14.609644294937652, 50.02081908813608 ]
      ]] 
  }, 
  "properties" : {  
    "Name" : "Region 1" 
  } 
}

And the query I’m trying to construct is something like this:

db.points.aggregate([
  {$project: {
    coordinates: ["$gps.lon", "$gps.lat"]
  }}, 
  {$lookup: {
    from: "regions", pipeline: [
      {$match: {
        coordinates: {
          $geoWithin: {
            $geometry: {
              type: "Polygon", 
              coordinates: "$geometry.coordinates"
            }
          }
        }
      }}
    ], 
    as: "district"
  }}
])

I’m getting an error:

assert: command failed: {

    "ok" : 0,
    "errmsg" : "Polygon coordinates must be an array",
    "code" : 2,
    "codeName" : "BadValue"

} : aggregate failed

I’ve noticed the structure of $geoWithin document is same as structure of one I have for each region. So I tried such query:

db.points.aggregate([
  {$project: {
    coordinates: ["$gps.lon", "$gps.lat"]
  }}, 
  {$lookup: {
    from: "regions", pipeline: [
      {$match: {
        coordinates: {
          $geoWithin: "$geometry.coordinates"
        }
      }}
    ], 
    as: "district"
  }}
])

The error was same.

I looked up for geoqueries but surprisingly all found mentions had static region document instead of one taken from a collection. So I’m wondering - is it ever possible to map points with regions having that both document collections aren’t static and taken from DB?

Hi @Mychajlo_Chodorev, welcome!

In order to use expressive $lookup, the $match value in the pipeline requires to be an expression. Currently it’s not possible to use $geoWithin as an expression, there’s an open ticket for this SERVER-34766. Please feel free to watch/up-vote the ticket to receive update on it.

One way to achieve what you’ve described is to use a client application to query from Points collection then programmatically build a geo query for Regions collection .

Regards,
Wan.