2

How can I remove all "aFHJBrKu54y5mWjY3" in "newFor"?

Trying do this, but it does not work.

        Messages.update({
                users: { $all: ["CnugxoBWs4ox6vG2k", "aFHJBrKu54y5mWjY3"] }
            },
            {
                $pull: {
                    "messages.$.newFor": "aFHJBrKu54y5mWjY3"
                }
            },
            { multi: true }
        );
{
    "_id" : "gQnYi2e54zADwgipx",
    "users" : [ 
        "aFHJBrKu54y5mWjY3", 
        "CnugxoBWs4ox6vG2k"
    ],
    "lastMessageAt" : ISODate("2020-06-22T22:50:35.579Z"),
    "messages" : [ 
        {
            "id" : "4d2219d05645a3991d3aae89",
            "addedAt" : ISODate("2020-06-22T22:50:35.579Z"),
            "userId" : "CnugxoBWs4ox6vG2k",
            "newFor" : [ 
                "aFHJBrKu54y5mWjY3",
                "CnugxoBWs4ox6vG2k"
            ],
            "message" : "Test"
        }, 
        {
            "id" : "b42641118bb080cb9122062f",
            "addedAt" : ISODate("2020-06-22T22:48:24.359Z"),
            "userId" : "aFHJBrKu54y5mWjY3",
            "newFor" : [
                "aFHJBrKu54y5mWjY3"
            ],
            "message" : "Test 2"
        }, 
        {
            "id" : "244e77bb8324dc0b0f0e2def",
            "addedAt" : ISODate("2020-06-22T22:48:14.643Z"),
            "userId" : "CnugxoBWs4ox6vG2k",
            "newFor" : [ 
                "aFHJBrKu54y5mWjY3"
            ],
            "message" : "Test 3"
        }
    ]
}

2 Answers 2

1

Test yourself my answer: https://mongoplayground.net/p/vHx3J4zQgWr

Query:

db.collection.aggregate([
  {
    "$project": {
      "messages": {
        // for every element of messages array
        "$map": {
          "input": "$messages",
          "as": "m",
          "in": {
            // keep id
            "id": "$$m.id",
            // keep addedAt
            "addedAt": "$$m.addedAt",
            // keep userId
            "userId": "$$m.userId",
            // keep message
            "message": "$$m.message",
            // for every element of newFor, remove based on filter
            // $ne means "not equal"
            "newFor": {
              "$filter": {
                "input": "$$m.newFor",
                "as": "n",
                "cond": {
                  "$ne": [
                    "$$n",
                    "aFHJBrKu54y5mWjY3"
                  ]
                }
              }
            }
          }
        }
      }
    }
  }
])

Result:

[
  {
    "_id": "gQnYi2e54zADwgipx",
    "messages": [
      {
        "addedAt": ISODate("2020-06-22T22:50:35.579Z"),
        "id": "4d2219d05645a3991d3aae89",
        "message": "Test",
        "newFor": [
          "CnugxoBWs4ox6vG2k"
        ],
        "userId": "CnugxoBWs4ox6vG2k"
      },
      {
        "addedAt": ISODate("2020-06-22T22:48:24.359Z"),
        "id": "b42641118bb080cb9122062f",
        "message": "Test 2",
        "newFor": [],
        "userId": "aFHJBrKu54y5mWjY3"
      },
      {
        "addedAt": ISODate("2020-06-22T22:48:14.643Z"),
        "id": "244e77bb8324dc0b0f0e2def",
        "message": "Test 3",
        "newFor": [],
        "userId": "CnugxoBWs4ox6vG2k"
      }
    ]
  }
]
Sign up to request clarification or add additional context in comments.

Comments

1

The positional operator $ only matches the first array element that satisfies the query. Since you have not specified any criteria for messages in the query, it will not match anything.

In order to remove the elements from every newFor array nested within an anonymous object nested within the messages array, you will need to iterate the messages array, and filter each of the newFor arrays separately.

This is only possible in a single update command if you are using MongoDB 4.2+, using the pipeline form of the update database command.

db.messages.update({},[
    {$set:{
        messages:{
            $map:{
                input:"$messages",
                in:{
                    $mergeObjects:[
                        "$$this",
                        {newFor:{
                            $filter:{
                                input:"$$this.newFor",
                                as:"new",
                                cond:{$not:{$in:[
                                    "$$new",        
                                    ["aFHJBrKu54y5mWjY3","CnugxoBWs4ox6vG2k"]
                                ]}}
                            }
                         }}
                     ]
                }
             }
        }
    }}
])

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.