在 mongoDB 文档中设置和更新对象数组的许多行为

问题描述 投票:0回答:1

我在 mongoDB 中有一个文档,其中包含这两个数组 -

"CS_Currency": [
        {
            "name": "AUD"
        },
        {
            "name": "IVP"
        }
    ],
    "TestRef": [
        {
            "name": "Reftest"
        },
        {
            "name": "Ref5"
        },
        {
            "name": "RefChanged"
        }
    ],


现在当我写作时

db.getCollection('pipeline-entity').updateMany(
    { "TestRef.name": "RefChanged", "Entity_Type_Value.name":"Deal"},  
    { $set: { "TestRef.$.name": "Ref3" }
    })

此查询运行良好,并且 TestRef 数组的第三个元素被修改

但是当我运行这个查询时---

db.getCollection('pipeline-entity').updateMany(
    { "CS_Currency.name": "IVP", "Entity_Type_Value.name":"Deal"},  
    { $set: { "CS_Currency.$.name": "IVPChanged" }
    })

这会将数组的第一个元素(即 AUD)更改为 IVPChanged

你能说出为什么会出现这样的情况吗?或者如果我做错了什么?

mongodb robo3t
1个回答
0
投票

Entity_Type_Value
不在您的示例数据中,但它是更新选择查询的一部分。它可能是 {"name": "Deal"}
array
等。因此,这会影响更新期间的
$
位置。

如果只是一个单一的对象,如

"Entity_Type_Value": { "name": "Deal" }
那么它按预期工作

但是,如果它也是一个像这样的数组:

"Entity_Type_Value": [{ "name": "Deal" }, { "name": "No Deal" }]
那么它确实会影响结果并且哪个元素会被更新 - mongo Playground 与最小可重现示例针对所描述的问题

这实际上发生在您的两个查询中。在第一个查询中,它只是偶然/侥幸地匹配了正确的项目来更新,可能基于第二个数组匹配子句的索引。

你能说出为什么会出现这样的行为吗?或者如果我做错了什么?

来自文档(强调我的):

多个数组匹配

位置

$
更新运算符 在多个数组字段上过滤时表现不明确

当服务器执行更新方法时,它首先运行一个查询来确定要更新哪些文档。如果更新过滤多个数组字段上的文档,则对位置

$
更新运算符 的后续调用并不总是更新数组中所需的位置

文档还有一个示例,它显示了执行此操作时的错误行为。

解决方案:

1。改变数据结构:

如果您期望对象中的每个数组之间或对象中的某些数组之间存在某种有序关系。即

CS_Currency[0]

Entity_Type_Value[0]
 相关,并且可能与 
TestRef[0]
 相关 - 这是错误的。它们应该都在一个对象中,并且您仍然可以拥有它们的数组:

{ "CS_Currency": [ { "name": "AUD", "Entity_Type": "No Deal", "TestRef": "Reftest" }, { "name": "IVP", "Entity_Type": "Deal", "TestRef": "Ref5" } ] }

2。修复查询 IF-AND-ONLY-IF Entity_Type_Value

 数组中将只有一个对象
:

为“Entity_Type_Value”匹配添加

0

,以仅匹配该数组的第一个元素:

db.collection.update({ "CS_Currency.name": "IVP", // explcit match against FIRST element of Entity_Type_Value "Entity_Type_Value.0.name": "Deal" }, { $set: { "CS_Currency.$.name": "IVPChanged" } })

蒙戈游乐场

© www.soinside.com 2019 - 2024. All rights reserved.