Pull only one item in an array of instance in MongoDB?

Hello,

    {
    "_id":{"$oid":"5fa4386f3a93dc470c920d76"},
    "characters":[
    	{"$oid":"5fa4389e3a93dc470c920d78"},
    	{"$oid":"5fa4389e3a88888888888888"},
    	{"$oid":"5fa4389e3a88888888888888"},
    	{"$oid":"5fa4389e3a88888888888888"}
    	]
    }

I tryied to remove only one row of object id 5fa4389e3a88888888888888 in my characters array.
By doing…

User.findByIdAndUpdate("5fa4386f3a93dc470c920d76", { $pull: { characters: "5fa4389e3a88888888888888" } }, (err) => {});

The problem is that every row with “5fa4389e3a88888888888888” value are removed.
And I’d just like to pull 1.

Is it possible ?

Thanks for helping,

1 Like

Hello @Julien_LeGa, welcome to the MongoDB Community forum.

Here is an example about how to update / pull the first matching element from the array.

Consider a document: { "_id" : 1, "characters" : [ "9999", "8888", "5555", "8888" ] }

You want to remove the first matching "8888". Use the following aggregation update (requires MongoDB v4.2 or greater):

db.collection.updateOne( 
  { _id: 1 },
  [ 
    { $set: { 
         characters: {
             $let: {
                 vars: { ix: { $indexOfArray: [ "$characters", "8888" ] } },
                 in: { $concatArrays: [
                           { $slice: [ "$characters", 0, "$$ix"] },
                           [ ],
                           { $slice: [ "$characters", { $add: [ 1, "$$ix" ] }, { $size: "$characters" } ] }
                      ]
                 }
            }
        }
    }}
] )
3 Likes

I respect answer by @Prasad_Saya, I am just adding the another option Starting from MongoDB v4.4,

You can use update with aggregation pipeline, and use the $function operator to define custom functions to implement behavior not supported by the MongoDB Query Language.

User.findByIdAndUpdate("5fa4386f3a93dc470c920d76",
[
    {
        $set: {
            characters: {
                $function: {
                    body: function(characters) {
                        for (var i=0; i<characters.length; i++) {
                            if (characters[i] == "5fa4389e3a88888888888888") {
                                delete characters[i];
                                break;
                            }
                        }
                        return characters;
                    },
                    args: ["$characters"],
                    lang: "js"
                }
            }
        }
    }
])
1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.