MongoDB:从数组字段中的所有子文档中删除字段

时间:2013-08-23 18:05:48

标签: mongodb pymongo mongoengine

我有这种格式的数千份文件:

{
"_id" : ObjectId("51e98d196b01c2085c72d731"),
"messages" : [
    {
        "_id" : ObjectId("520167056b01c20bb9eee987"),
        "id" : ObjectId("520167056b01c20bb9eee987"),

    },
    {
        "_id" : ObjectId("520167056b01c20bb9eee988"),
        "id" : ObjectId("520167056b01c20bb9eee988"),

    },
    {
        "_id" : ObjectId("520167056b01c20bb9eee989"),
        "id" : ObjectId("520167056b01c20bb9eee989"),
    }
],
}

我需要删除重复的“id”字段。这就是我的尝试:

db.forum_threads.update({}, {$unset: {"messages.$.id": 1}}, {multi: true});

这是我得到的错误:

Cannot apply the positional operator without a corresponding query field containing an array.

2 个答案:

答案 0 :(得分:14)

您收到该错误的原因是您在filter子句中没有任何谓词。你可以这样做:

mongos> db.test.update({"messages.id": {$exists: true}}, {$unset: {"messages.$.id":true}}, {multi:true})

并且您不会收到错误 - 实际上其中一个文档将删除id属性。问题是位置运算符只匹配与谓词匹配的数组的FIRST元素,它不匹配所有元素。更大的问题是,目前无法更新MongoDB(https://jira.mongodb.org/browse/SERVER-1243)中数组中的所有元素。

您需要使用数字位置(“messages.0.id”,“messages.1.id”等)迭代数组中的每个元素,或者您可以将数组拉入您的应用程序,循环遍历元素并更新它们,然后将数组保存回来。

您可以从JIRA票证中看到此问题已经开放了很长一段时间,但10gen似乎并不认为它是非常高优先级。

答案 1 :(得分:0)

使用Mongo 3.6,您可以使用新的positional identifier并执行以下操作:

db.test.update({"messages.id": {$exists: true}}, {$unset: {"messages.$[].id":true}}, {multi:true})