Eric Mbairamadji
Eric Mbairamadji

Reputation: 33

Mongoose : Can't populate after find to make $near query

I am trying to populate user informations to get his location but i am getting undefined. Here are my schemas:

AnnounceSchema:

const AnnounceSchema = new mongoose.Schema({
  titre: String,
  contenu: String,
  image: String,
  tag: String,
  media: String,
  date: {
    type: Date,
    default: Date.now
  },
  commentaires: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }],
  authorId: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
})

UserSchema:

const UserSchema = new mongoose.Schema({
  username: { type: String, required: true, unique: true },
  password: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  loc: { type: { type: String, default: 'Point' }, coordinates: { type: [Number] } }
});
UserSchema.index({ loc: '2dsphere' });

And here is my query :

Announce.find({})
  .populate('authorId', null,
    {
      'authorId.loc': {
        $near: {
          $geometry: {
            type: 'Point',
            coordinates: [req.user.loc.coordinates[0], req.user.loc.coordinates[1]]
          },
          $maxDistance: 10000
        }
      }
    })
  .exec((err, announces) => {
    if (err) {
      res.send(err)
    } else {
      res.render('announce/search', { announces: announces })
    }
  })

The error I'm getting is "unable to find index for $geoNear query". I've added an index to the AnnonceSchema but no change:

AnnonceSchema.index({ "authorId.loc" : "2dsphere"})

Upvotes: 1

Views: 121

Answers (1)

m1ch4ls
m1ch4ls

Reputation: 3435

This should work:

Announce.find({})
  .populate('author',
    {
      path : 'authorId',
      match: {
        'loc': {
          $near: {
            $geometry: {
              type: 'Point',
              coordinates: [req.user.loc.coordinates[0], req.user.loc.coordinates[1]]
            },
            $maxDistance: 10000
          }
        }
      },
      model: 'User',
    })
  .exec((err, announces) => {
    if (err) {
      res.send(err)
    } else {
      res.render('announce/search', { announces: announces })
    }
  })

populate works in two ways

  • it can populate by reference Announce.find({}).populate('authorId')
  • or by a custom query (which is what you need)

Upvotes: 1

Related Questions