Ron
Ron

Reputation: 4095

lookup with pipeline and geoIntersects that use let variable

I am trying to lookup for neighborhoods which match my condition - the boundries polygon intersects with the post's coordinates but I am unable to do it - cant use the let in my pipeline $match

example of post entity:

{
  _id: ObjectId,
  ...,
  location: {
    ...,
    coordinates: {
      type: 'Point',
      coordinates: [number, number]
    }
  }
};

example of neighborhood entity:

{
  _id: ObjectId,
  ...,
  boundries: {
    type: 'Polygon',
    coordinates: [ [ [number, number], [number, number], [number, number], [number, number], [number, number] ] ]
  }
};

example of query I am trying to "fix":

db.posts.aggregate([
  { $match: { _id: ObjectId('5a562e62100338001218dffa') } },
  {
    $lookup: {
      from: 'neighborhoods',
      let: { postCoordinates: '$location.coordinates.coordinates' },
      pipeline: [
        {
          $match: {
            boundries: {
              $geoIntersects: {
                $geometry: {
                  type: 'Point',
                  coordinates: '$$postCoordinates'
                }
              }
            }
          }
        }
      ],
      as: 'neighborhoods'
    }
  }
]);

Upvotes: 9

Views: 1174

Answers (1)

s7vr
s7vr

Reputation: 75954

Unfortunately coordinates can't be populated from document field.

Geospatial are query expressions and $let variables are only permitted to use in $match with $expr variant for aggregation expressions in $lookup pipeline.

You have to perform the query in two steps.

First step to get the coordinates for matching record.

var result =  db.posts.findOne({ _id: ObjectId('5a562e62100338001218dffa')},{ _id: 0, 'location':1});

Second step to look for point in the polygon.

db.neighborhoods.find(
   {
     "boundries": {
       $geoIntersects: {
          $geometry: {
             type: "Point" ,
             coordinates: result.location.coordinates.coordinates
          }
       }
     }
   }
)

Upvotes: 4

Related Questions