Snoopy
Snoopy

Reputation: 1357

MongoDB $addToSet wiith some logic

The end goal is to add a new partner to the partners list per pathway object IF they don't already exist. AND if the pathway_name does not equal Engagement Team.

I would want to add the following partner for example:

{
                    "_id" : ObjectId("5dd5762be13e15a73f042ce5"), 
                    "partner" : ObjectId("5dd57633bf0cbbbb36bc112f")
}

 "pathways" : [
        {
            "_id" : ObjectId("5d837689b57cc711487f1cf0"), 
            "pathway_name" : "Electronics Technology with Advanced Manufacturing Mechatronics", 
            "partners" : [
                {
                    "_id" : ObjectId("5d837ab8b57cc711487f1d28"), 
                    "partner" : ObjectId("5d837426b57cc711487f1c96")
                }
            ]
        }, 
        {
            "_id" : ObjectId("5d837694b57cc711487f1cf1"), 
            "pathway_name" : "Pre-Mechanical Engineering", 
            "partners" : [
                {
                    "_id" : ObjectId("5d837acfb57cc711487f1d29"), 
                    "partner" : ObjectId("5d837421b57cc711487f1c92")
                }
            ]
        }, 
        {
            "_id" : ObjectId("5da6055da0eb361cc8da26dc"), 
            "pathway_name" : "Engagement Team", 
            "partners" : [
                {
                    "_id" : ObjectId("5da60711a0eb361cc8da26f0"), 
                    "partner" : ObjectId("5d83749fb57cc711487f1cc2")
                }
            ]
        }
    ], 

My current query is as follows, i'm not sure how to add the logic of only adding the partner if they don't exist based off the partner field itself and not the _id field of a partner object.

db.getCollection("schools").updateMany({}, $addToSet:{"pathways$[].partners"})

Expected Result:

 "pathways" : [
        {
            "_id" : ObjectId("5d837689b57cc711487f1cf0"), 
            "pathway_name" : "Electronics Technology with Advanced Manufacturing Mechatronics", 
            "partners" : [
                {
                    "_id" : ObjectId("5d837ab8b57cc711487f1d28"), 
                    "partner" : ObjectId("5d837426b57cc711487f1c96")
                },
                {
                    "_id" : ObjectId("5dd5762be13e15a73f042ce5"), 
                    "partner" : ObjectId("5dd57633bf0cbbbb36bc112f")
                }
            ]
        }, 
        {
            "_id" : ObjectId("5d837694b57cc711487f1cf1"), 
            "pathway_name" : "Pre-Mechanical Engineering", 
            "partners" : [
                {
                    "_id" : ObjectId("5d837acfb57cc711487f1d29"), 
                    "partner" : ObjectId("5d837421b57cc711487f1c92")
                },
                {
                    "_id" : ObjectId("5dd5762be13e15a73f042ce5"), 
                    "partner" : ObjectId("5dd57633bf0cbbbb36bc112f")
                }
            ]
        }, 
        {
            "_id" : ObjectId("5da6055da0eb361cc8da26dc"), 
            "pathway_name" : "Engagement Team", 
            "partners" : [
                {
                    "_id" : ObjectId("5da60711a0eb361cc8da26f0"), 
                    "partner" : ObjectId("5d83749fb57cc711487f1cc2")
                }
            ]
        }
    ], 


Upvotes: 0

Views: 365

Answers (1)

whoami - fakeFaceTrueSoul
whoami - fakeFaceTrueSoul

Reputation: 17915

Please try it and let me know :

db.getCollection("schools").update(
    {},
    {
        $push: {
            'pathways.$[eachPathway].partners': {
                "_id": ObjectId("5dd5762be13e15a73f042ce5"),
                "partner": ObjectId("5dd57633bf0cbbbb36bc112f")
            }
        }
    },
    { arrayFilters: [{ $and: [{ "eachPathway.pathway_name": { $ne: "Engagement Team" } },
    {"eachPathway.partners._id":{$ne: ObjectId("5dd5762be13e15a73f042ce5")}}]}], multi: true }
)

Note : Seems like $addToSet doesn't work on entire object comparison, So we need to compare at at least one field from the input object with the same field in objects from the array. Atlast we can use $push, as duplicate objects are already filtered out, but not sure how to achieve it if you need entire object comparison - I think it might not be needed though.

Might See this error or no docs being updated :

No array filter found for identifier 'eachPathway' in path 'pathways.$[eachPathway].partners'

In short, this is because robo3T or any-other mongoDB client which is being used is not able to process arrayFilters, So to test this query please directly test it using code.

Ref : No array filter issue

Upvotes: 1

Related Questions