MongoDB:更新内部BSON的值

时间:2016-05-10 17:57:32

标签: mongodb mongodb-query

我有一个mongodb架构的文档,如下所示:

{
    "_id" : ObjectId("572f88424de8c74a69d4558c"),
    "storecode" : "ABC",
    "credit" : true,
    "group" : [
        {
            "group_name" : "Frequent_Buyer",
            "time" : NumberLong("1462732865712"),
        }
    ],
}

我想在_id下为group下的数组中的第一个对象添加{ "_id" : ObjectId("572f88424de8c74a69d4558c"), "storecode" : "ABC", "credit" : true, "group" : [ { "group_name" : "Frequent_Buyer", "time" : NumberLong("1462732865712"), "_id" : "573216fee4430577cf35e885" } ], } 部分,所以它看起来像这样:

db.customer.update({ "_id": ObjectId("572f88424de8c74a69d4558c") },{ "$set": { "group.$._id": "573216fee4430577cf35e885"} })

WriteResult({
    "nMatched" : 0,
    "nUpserted" : 0,
    "nModified" : 0,
    "writeError" : {
        "code" : 16837,
        "errmsg" : "The positional operator did not find the match needed from the query. Unexpanded update: groups.$._id"
    }
})

当我尝试使用此代码时,它失败了:

db.customer.update({ "_id": ObjectId("572f88424de8c74a69d4558c"), "group.groupname": "Frequent_Buyer" },{ "$set": { "group.$._id": "573216fee4430577cf35e885"} })

但是,如果我稍微调整代码并添加额外的查询条件,则可以正常工作:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

结果:

List<object> obj = new List<object>();
obj.Add(new {id = 1, name = "Jakob"});
obj.Add(new {id = 2, name = "Sam"});
obj.Add(new {id = 3, name = "Albert"});
obj.Add(new {id = 1, name = "Jakob"});

为什么第一个命令不起作用,但第二个命令有效?

1 个答案:

答案 0 :(得分:1)

这是预期的结果。要使用位置$更新运算符,数组字段必须显示为查询文档的一部分,如documentation.

中所述
  

与更新操作一起使用时,例如db.collection.update()db.collection.findAndModify()

     
      
  • 位置 $ 运算符充当与查询文档匹配的第一个元素的占位符,
  •   
  • 数组字段必须作为查询文档的一部分出现。
  •   

例如,如果您不想使用group_name过滤文档,只需在查询条件中添加group: { "$exists": true }"group.0": { "$exists": true }即可。您的查询将如下所示:

db.customer.updateOne(
    { 
        "_id": ObjectId("572f88424de8c74a69d4558c"), 
        "group.0": { "$exists": true}
    },
    { "$set": { "group.$._id": "573216fee4430577cf35e885" } }
)

最后也是最重要的一点,您应该使用updateOneupdateMany,因为在官方语言驱动程序中不推荐使用更新。