我有一个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"});
为什么第一个命令不起作用,但第二个命令有效?
答案 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" } }
)
最后也是最重要的一点,您应该使用updateOne
或updateMany
,因为在官方语言驱动程序中不推荐使用更新。