简体   繁体   中英

MongoDB - Pull from array of objects

I have a collection

{
    "_id" : ObjectId("534bae30bf5049a522e502fe"),
    "data" : [
            {
                    "0" : {
                            "content" : "1",
                            "type" : "text",
                            "ident" : true
                    },
                    "1" : {
                            "content" : "",
                            "type" : "text",
                            "ident" : false
                    }

            },
            {
                    "0" : {
                            "content" : "2",
                            "type" : "text",
                            "ident" : true
                    },
                    "1" : {
                            "content" : "",
                            "type" : "text"
                    }
            }
    ]

}

content is unique.

How would i remove the object that matches content: '2' ?

I have tried this:

data:{$pull:{"content": deletions[i]}}

where deletions [i] is the content.

and several variations, but i can not get it to work. What am I missing?

As per you comment, you should be worried. I have seen this a few times particularly with PHP applications ( and PHP has this funny kind of notation in dumping arrays ).

The problem is the elements such as the "0" and "1" create sub-documents in themselves, and as opposed to just leaving everything under that structure as the sub-document in itself as the the array member then you run into a problem with accessing individual members of the array as the paths used need to be "absolute".

So this actually "forces" no other possible option to access the elements by what would be the equivalent "dot notation" form. Except in this case it's not just the "nth" element of the array, but the actual path you need to address.

But if this does actually work for you, and it does seem like "someone" was trying to avoid the problems with positional updates under "nested" arrays ( see the positional $ operator documentation for details ) then you update can be performed like this:

The basic statement is as follows:

db.collection.update(
    {
        "data.0.context": 2
    },
    {
        "$pull": { "data.$.0.context": 2 }
    }
)

That does "seem" to be a bit of a funny way to write this, but on investigating the actual structure you have then you should be able to see the reasons why this is needed. Essentially this meets the requirements of using the positional $ operator to indicate the index of the first matched element in the array ( aka "data" ) and then uses the standard sub-document notation in order to specify the path to the element to be updated.

So of course this poses a problem if the element is actually in an unknown position. But the thing to consider is which usage of the array is actually important to you given the documented limitation? If yo need to match the position of the "inner" element, then change the structure to put the arrays in there.

But always understand the effects of the limitation, and try to model according to what the engine can actually do.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM