更新MongoDB中的嵌套对象

更新MongoDB中的嵌套对象,mongodb,mongodb-query,Mongodb,Mongodb Query,我正在尝试更新MongoDB中的一个嵌套文档,它看起来类似于下面的内容(缩写为简明) { “科尔斯”:“20”, “保存时间”:“2014-06-15-10:44:09”, “行”:“20”, “配子ID”:“66f2497c-7a2b-4210-a06b-80be0e6a8fd8”, “玩家”:[ { “id”:“不人道”, “num”:“1”, “颜色”:“00ff00ff”, “名称”:“坏电脑”, “类型”:“1” }, ], “节点”:[ { “g”:“1”, “c”:“0”, “r”

我正在尝试更新MongoDB中的一个嵌套文档,它看起来类似于下面的内容(缩写为简明)

{
“科尔斯”:“20”,
“保存时间”:“2014-06-15-10:44:09”,
“行”:“20”,
“配子ID”:“66f2497c-7a2b-4210-a06b-80be0e6a8fd8”,
“玩家”:[
{
“id”:“不人道”,
“num”:“1”,
“颜色”:“00ff00ff”,
“名称”:“坏电脑”,
“类型”:“1”
},
],
“节点”:[
{
“g”:“1”,
“c”:“0”,
“r”:“0”,
“a”:“0”,
“o”:”
},
{
“g”:“1”,
“c”:“0”,
“r”:“1”,
“a”:“0”,
“o”:”
}
],
}
我要做的是更新其中一个节点。例如,我想更改节点:

{“g”:“1”、“c”:“0”、“r”:“0”、“a”:“0”、“o”:“}

{“g”:“1”、“c”:“0”、“r”:“0”、“a”:“5”、“o”:“}
我已经尝试使用点(.)符号和$set命令,ala:

db.game.update({“gameID”:“66f2497c-7a2b-4210-a06b-80be0e6a8fd8”},{$set:{“nodes.r”:“0”,“nodes.c”:“0”,“nodes.a”:“5”}),

但这并没有给我预期的行为,因为我正在用相同的r和c值更新所有节点。这显然不是我想要的,但我不知道如何更新此文档的特定部分。有人知道怎么做吗?

要更新特定节点,您需要将其放在搜索的查询部分

  db.game.update({"gameID" : "66f2497c-7a2b-4210-a06b-80be0e6a8fd8","nodes.r":"0", 

  "nodes.c":"0", "nodes.a":"5" }, { $set: {"nodes.$.r":"0",   "nodes.$.c":"0", "nodes.$.a":"5"}})
您可以看到,将获取它找到的与调用的第一部分(查询)匹配的节点对象,并在调用的第二部分(投影)中发送给您。
另外

如果您希望更新“节点”数组中的特定项,但您不知道该项的位置,但知道与该项匹配的“标准”,则需要在更新端使用运算符和运算符:

db.game.update(
    {
        "gameID" : "66f2497c-7a2b-4210-a06b-80be0e6a8fd8",
        "nodes": { "$elemMatch": { "g": 1, "r": 0 } } 
    },
    { "$set": { "nodes.$.c":"0", "nodes.$.a":"5" } }
)
运算符包含与查询条件“匹配”的第一个元素的匹配“索引”位置。如果不使用并改用“点表示法”形式,则匹配仅对包含值的整个文档有效,该值将为true,并且不反映匹配两个字段条件的元素的“位置”

必须注意的是,这是“第一次”匹配,通常预期是唯一的匹配。原因是位置运算符将仅包含存在多个匹配项的“第一个”位置。要以这种方式更新多个与条件匹配的数组项,则需要多次发出更新,直到不再修改文档为止

对于“已知”位置,您始终可以直接使用“点符号”形式,包括要更新的元素的位置:

db.game.update(
{
“配子ID”:“66f2497c-7a2b-4210-a06b-80be0e6a8fd8”,
},
{“$set”:{“nodes.0.c”:“0”,“nodes.0.a”:“5”}
)
因此,第一个元素的索引位置为
0
,第二个元素的索引位置为
1
,依此类推


请注意,在这两种情况下,您只需要传递到实际要更改的字段。因此,除非您不确定某个值是否存在(如果这是您的查询,则情况并非如此),否则您不需要将字段“设置”为它们已经包含的值。

实际上,这只会在提供的数据上匹配,因为元素是数组中的“第一”项。要正确匹配多个条件,您需要
$elemMatch
,因为文档本身包含各种数组元素,所以此处指定的条件与“文档”本身匹配,只返回数组的第一个位置。是的,您是对的!这实际上不是正确的,谢谢你的信息,但有一个问题。节点数组中只有一个元素具有给定的r和c(行和列)值。是否仍有必要这样做,或者orepor的上述回答是否有效?@unaligned No它将不起作用,这就是为什么我也向他们发表评论,以征求他们的理解。假设您正在寻找
{“g”:,“r”:1}
。除非您使用
$elemMatch
,否则这确实与“文档”匹配,该“文档”在数组中包含与条件匹配的元素。但是his实际上并不匹配阵列的正确位置,除非您使用
$elemMatch
。链接文档显示了其他示例。但这两个属性几乎永远不会以这种方式匹配,除非是偶然的。