Watch keynotes and sessions from MongoDB.live, our virtual developer conference.

$geoNear in aggregation pipeline

Hello, I’m aware that $geoNear must be used as the first stage in an aggregation pipeline, but unfortunately I’m doing a $lookup as the third stage in my pipeline, and it’s on that schema that the 2dsphere indexed property exists. Here’s a simplification:

List Schema:

const ListSchema = mongoose.Schema({
  placeIds: { // 1
    default: [],
    index: true,
    ref: 'Place',
    type: [mongoose.Schema.Types.ObjectId]
  },
  ...
})
  1. A list can contain multiple Place ObjectId.

Place Schema:

const PlaceSchema = mongoose.Schema({
  geo_point: {
    index: '2dsphere',
    select: false,
    type: [Number]
  },
  ...
})

My goal is to find the most popular places near a location.

My current approach uses the following pipeline:

const results = await List.aggregate([
  { $unwind: '$placeIds' },
  { $sortByCount: '$placeIds' }, // 1
  { $lookup: { as: 'place', foreignField: '_id', from: 'places', localField: '_id' } }, // 2
  { $unwind: '$place' },
  { $replaceRoot: { newRoot: '$place' } }, // 3
  // we now have an array of places that we can match on
  { $match: { ... }
])
  1. Find popular placeId. For the time being, “popular” is defined as sorting all the placeId ObjectIds descending by the number of List documents they’re contained on.
  2. Lookup the actual Place document from a different collection.
  3. Replace the current objects with the Place document, giving us an array of Place.

Is there a different approach that I can take to better accomplish this? Thanks!