1

My code:

questionSchema.statics.getRandomByUser = function getRandomByUser(user) {
  const aggr = [{ $sample: { size: 1 } }];
  console.log(`user.answered = ${user.answered}`);
  if (user.answered.length || user.categories.length) {
    const match = { $match: {} };
    if (user.answered.length) match.$match._id = { $nin: user.answered };
    if (user.categories.length) match.$match.category = { $in: user.categories };
    aggr.unshift(match);
  }

  console.log(`aggr = ${JSON.stringify(aggr)}`);
  return this.model('question').aggregate(aggr);
};

In result aggregate is:

[{"$match":{"_id":{"$nin":["5c7bb1d08f999f326151df49","5c7bb1d08f999f326151df49"]},"category":{"$in":["Test"]}}},{"$sample":{"size":1}}]

Filter by category works fine. But my $nin just ignored. How I must use $nin with _id to omit unwanted documents?

Mikita Melnikau
  • 1,655
  • 2
  • 15
  • 30
  • Even though this is marked as [duplicate], I think the question is very useful, because it deals with $nin. There are not a lot of examples of $nin. Thanks for sharing – Izzi Aug 27 '20 at 09:07

1 Answers1

5

_id in mongoDb is usually an ObjectId which is a 24 charachter hexadecimal unique key.

You can convert the string _id to ObjectId and then query

[{"$match":{"_id":{"$nin":[ObjectId("5c7bb1d08f999f326151df49"),ObjectId("5c7bb1d08f999f326151df49")]},"category":{"$in":["Test"]}}},{"$sample":{"size":1}}]
HIRA THAKUR
  • 17,189
  • 14
  • 56
  • 87
  • so what will the best solution? save `ObjectId`'s in array or create additional index (as I did now)? – Mikita Melnikau Mar 03 '19 at 14:49
  • @MikitaMelnikau from what I understand, If your unique key in `user ` i.e _id is an ObjectId, you should convert your id from string to ObjectId in your script. MongoDb by default, sets _id as an ObjectId, not as plain string like you are querying. – HIRA THAKUR Mar 03 '19 at 14:53
  • _id is by default ,indexed in mongo. Just make sure your data types are correct. – HIRA THAKUR Mar 03 '19 at 15:32