'Fetch records that does not exists in collection in given array - mongodb

I have an array of student ids.

I want to get those records that were not found from the given array.

Students array:

var studentIds = [1, 2, 3, 4, 5];

Records in collection:

[{_id: 1, name: 'John'}, {_id: 4, name: 'mike'}]

Now the desired output I require is:

[2, 3, 5]

What I have tried so far which is not providing the right response:

Students.aggregate([
    {
        $match: {
            _id: { "$nin": studentIds },
            status: "active"
        }
    },
    {
        $group: {
            _id: null,
            "idnotIntheArray": {$push: "$_id"}
        }
    }
]);

Can anyone find what I am doing wrong here?



Solution 1:[1]

Query

  • one way to do it is to create a new collection with 1 document with that array
  • unwind that array
  • and then lookup with the other collection(the students), if no match => id not found so we keep that id

*The above solution is for MongoDB < 5.1, if you have MongoDB 5.1 + you dont need to insert data to the collection, you can start from an empty collection and you can use this as first stage
{ $documents: [{"studentIds": [1, 2, 3, 4, 5]}] },

You can test it online in Playmongo

Collections (2 collections "array" and "students")

[
 "array",
 [{"studentIds": [1, 2, 3, 4, 5]}],
 "students",
 [{"_id": 1, "name": 'John'}, {"_id": 4, "name": 'mike'}]
]

Query
("array" is the collection you created with 1 document, with the array)

array.aggregate(
[{"$unwind": "$studentIds"},
 {"$lookup": 
   {"from": "students",
    "localField": "studentIds",
    "foreignField": "_id",
    "as": "results"}},
 {"$match": {"$expr": {"$eq": ["$results", []]}}},
 {"$group": {"_id": null, "not-found-ids": {"$push": "$studentIds"}}}])

Results

[{
  "_id": null,
  "not-found-ids": [
    2,
    3,
    5
  ]
}]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1