How to remove an element from an array that is nested inside another array using MongoDB

Problem

Suppose I have a document as follows:

doc = {
"_id" : ObjectId("56464c726879571b1dcbac79"),
"food" : {
    "fruit" : [
        "apple",
        "orange"
    ]
},
"items" : [
    {
        "item_id" : 750,
        "locations" : [
            {
                "store#" : 13,
                "num_employees" : 138
            },
            {
                "store#" : 49,
                "num_employees" : 343
            }
        ]
    },
    {
        "item_id" : 650,
        "locations" : [
            {
                "store#" : 12,
                "num_employees" : 22
            },
            {
                "store#" : 15,
                "num_employees" : 52
            }
        ]
    }
]
}


I would like to delete an item

    {'#store#' : 12, 'num_employees' : 22} 

but only if the following conditions are met:

  • food.fruitcontain values appleororange
  • item_id has id 650



My favorite solution

I tried the following:

     db.test.update({"food.fruit" : {"$in" : ["apple", "orange"]}, "items.item_id":650},{$pull:{'items.$.locations':{'store#':12,'num_employees':22}}})


The update does not work. Interestingly, if part of the $ in operator is removed, it works. I am using MongoDB v3.0.6 and consulted the MongoDB manual for using $ (update) :

https://docs.mongodb.org/manual/reference/operator/update/positional/

Documents contain interesting interest:

  Nested Arrays
  The positional $ operator cannot be used for queries which traverse more than one array, such as queries that traverse arrays nested within other arrays, because the replacement for the $ placeholder is a single value

, , . , 'food.fruit' : {$in : ['apple']} , . , , , . , :

  • .
  • /
+4
2

"food.fruit" , , ( , ), $in JavScript $where:

db.test.update(
    {
        "items.item_id": 650,
        "$where": function() {
            return this.food.fruit.some(function(el) {
                return ["apple","orange"].indexOf(el) != -1;
            });
        }
    },
    { "$pull": { "items.$.locations": { "store#": 12 } } },
    { "multi": true }
)

, , "food.fruit" , , , "items.item_id " , , , .

, MongoDB 3.1.9 ( ), :

db.test.update(
    { "food.fruit": { "$in": ["orange","apple"] }, "items.item_id": 650 },
    { "$pull": { "items.$.locations": { "store#": 12 } } },
    { "multi": true }
)

, _id , , , $pull :

db.test.update(
    { "_id": 123, "items.item_id": 650 },
    { "$pull": { "items.$.locations": { "store#": 12 } } }
)

, , , "food.fruits" , . .

+1

,

, :

db.pTest.update(
    {"food.fruit" : "apple","items.item_id":650},
    {$pull:{'items.$.locations':{'store#':12,'num_employees':22}}}
)

$in ( ) $elemMatch. {$pull: {"someArray.$.someNestedArray": {"key": "value to delete"}}}.

.

   positional $ , , , , , $placeholder .

, , $ Positional .

:

{
    "_id" : ObjectId("56464c726879571b1dcbac79"),
    "food" : {
        "fruit" : [
            "apple",
            "orange"
        ]
    },
    "items" : [
        {
            "item_id" : 650,
            "locations" : [
                {
                    "store#" : 12,
                    "num_employees" : 22
                },
                {
                    "store#" : 15,
                    "num_employees" : 52
                }
            ]
        }
    ]
}

:

{
    "_id" : ObjectId("56464c726879571b1dcbac79"),
    "food" : {
        "fruit" : [
            "apple",
            "orange"
        ]
    },
    "items" : [
        {
            "item_id" : 650,
            "locations" : [
                {
                    "store#" : 15,
                    "num_employees" : 52
                }
            ]
        }
    ]
}
0

Source: https://habr.com/ru/post/1615822/


All Articles