pullAll同时删除嵌入的对象

Bar*_*art 3 mongodb mongodb-query

我有以下文件的数据库:

> 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"
                }
        ]
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试编写查询以从奖项数组中删除由"Stockholm"或"Hollywood"发布的奖励对象,但以下查询不起作用:

> 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\
" } ]})"
        }
})
>
Run Code Online (Sandbox Code Playgroud)

类似的查询适用于从contribs数组中删除项目:

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

所以这里的问题似乎与我正在处理嵌入式对象的事实有关.

我很感激你的帮助.

谢谢!

Nei*_*unn 6

$pullAll运营商实际上是一个"特例"的快捷方式,其在阵列上的工作只有在他们的价值观,如您的另一种情况.

你真正想要的是$pull它的参数是对数组中包含的文档的"查询".因此,您的列表将成为以下参数$in:

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

所以在你的另一个例子中,更长的形式$pullAll是:

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

同样的事情,但只是"速记"的形式.