1

We have a request collection ,with example documents as below:

{
    "_id" : ObjectId("xxxxxx"),
    "requestId" : "REQ4",
    "scrip" : "5647"
}
{
    "_id" : ObjectId("xxxxxx"),
    "requestId" : "REQ4",
    "scrip" : "5648"
}
{
    "_id" : ObjectId("xxxxxx"),
    "requestId" : "REQ1",
    "scrip" : "0001"
}
{
    "_id" : ObjectId("xxxxxx"),
    "requestId" : "REQ1",
    "scrip" : "0456"
}

Scrips collection :

{
    "_id" : ObjectId("xxxx"),
    "scrip" : "0001"
}
{
    "_id" : ObjectId("xxxx"),
    "scrip" : "0456"
}
{
    "_id" : ObjectId("xxxx"),
    "scrip" : "5647"
}

We need to return the requests which have all the corresponding scrip in the Scrips collection.

Expected Output :

{"_id" : ObjectId("xxxxxx"),
    "requestId" : "REQ1",
    "scrip" : ["0001","0456"]
}

How do we achieve this?

IUnknown
  • 9,301
  • 15
  • 50
  • 76

1 Answers1

0

Try this :

db.requests.aggregate([
    /** Filter to reduce dataset */
    { $match: { requestId: { $in: ['REQ4', 'REQ1', 'REQ5'] } } },
    /** check for matching docs based on scrip */
    {
        $lookup:
        {
            from: "scrips",
            localField: "scrip",
            foreignField: "scrip",
            as: "scrips"
        }
    }, { $addFields: { scrips: { $arrayElemAt: ['$scrips', 0] } } },
    /** Group all docs in request collection based on requestId */
    { $group: { _id: '$requestId', scrip: { $push: '$scrip' }, scrips: { $push: '$scrips' } } },
    /** Remove request docs if all request docs doesn't have match in scrips */
    { $match: { $expr: { $eq: [{ $size: '$scrip' }, { $size: '$scrips' }] } } },
    /** Transform final result */
    { $project: { _id: 0, requestId: '$_id', scrip: 1 } }
])

Test : MongoDB-Playground

whoami - fakeFaceTrueSoul
  • 17,086
  • 6
  • 32
  • 46