4

I have database with following document:

> db.bios.find({"name.first":"James"}).pretty()
{
        "_id" : 9,
        "name" : {
                "first" : "James",
                "last" : "Gosling"
        },
        "birth" : ISODate("1955-05-19T04:00:00Z"),
        "contribs" : [
                "Java",
                "C",
                "Scala",
                "UNIX"
        ],
        "awards" : [
                {
                        "award" : "The Economist Innovation Award",
                        "year" : 2002,
                        "by" : "The Economist"
                },
                {
                        "award" : "Officer of the Order of Canada",
                        "year" : 2007,
                        "by" : "Canada"
                },
                {
                        "award" : "nobel",
                        "by" : "Stockholm"
                },
                {
                        "award" : "nobel2",
                        "by" : "Stockholm"
                },
                {
                        "award" : "oscar",
                        "year" : 2015,
                        "by" : "Hollywood"
                }
        ]
}

I'm trying to write query to remove award objects issued by "Stockholm" or "Hollywood" from the awards array, but the below query does not work:

> db.bios.update({"name.first":"James"}, {$pullAll:{"awards.by":["Stockholm","Hollywood"]}})
WriteResult({
        "nMatched" : 0,
        "nUpserted" : 0,
        "nModified" : 0,
        "writeError" : {
                "code" : 16837,
                "errmsg" : "cannot use the part (awards of awards.by) to travers
e the element ({awards: [ { award: \"The Economist Innovation Award\", year: 200
2.0, by: \"The Economist\" }, { award: \"Officer of the Order of Canada\", year:
 2007.0, by: \"Canada\" }, { award: \"nobel\", by: \"Stockholm\" }, { award: \"n
obel2\", by: \"Stockholm\" }, { award: \"oscar\", year: 2015.0, by: \"Hollywood\
" } ]})"
        }
})
>

Similar query works for removing items from contribs array:

> db.bios.update({"name.first":"James"}, {$pullAll:{"contribs":["Java","Fortran"
]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

so the problem here seems to be with the fact that I'm dealing with embedded object.

I'd appreciate your help.

Thanks!

1 Answer 1

10

The $pullAll operator is actually a "special case" shortcut which works on arrays with just values in them, such as your alternate case.

What you really want is $pull and it's argument is a "query" for the documents contained in the array. So your list then becomes an argument to $in:

db.bios.update(
   { "name.first": "James" },
   { 
      "$pull": { 
         "awards": { "by": { "$in": ["Stockholm", "Hollywood"] } } 
      } 
   }
)

So in your other example, a longer form of $pullAll would be:

db.bios.update(
   { "name.first": "James" },
   {
       "$pull": { "contribs": { "$in": ["Java","UNIX"] } }
   }
)

Same thing but just the "longhand" form.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.