Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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'
    }
  }
]);
like image 248
Ron Avatar asked Sep 06 '18 14:09

Ron


People also ask

What is let in lookup?

Definition. $let. Binds variables for use in the specified expression, and returns the result of the expression.

What is $$ in MongoDB?

To access the value of the variable, prefix the variable name with double dollar signs ( $$ ); i.e. "$$<variable>" . If the variable references an object, to access a specific field in the object, use the dot notation; i.e. "$$<variable>.

What are Lookup in aggregation for MongoDB?

$lookup performs an equality match on the localField to the foreignField from the documents of the from collection. If an input document does not contain the localField , the $lookup treats the field as having a value of null for matching purposes.

What is $project in MongoDB?

The $project takes a document that can specify the inclusion of fields, the suppression of the _id field, the addition of new fields, and the resetting of the values of existing fields. Alternatively, you may specify the exclusion of fields. Specifies the inclusion of a field.


1 Answers

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
          }
       }
     }
   }
)
like image 156
s7vr Avatar answered Sep 20 '22 17:09

s7vr