【问题标题】:Mongodb error: The positional operator did not find the match needed from the query [duplicate]Mongodb错误:位置运算符没有从查询中找到所需的匹配项[重复]
【发布时间】:2016-10-03 09:44:53
【问题描述】:

我有一个像这样的对象的集合

{
    "_id" : ObjectId("5742be02289512cf98bf63e3"),
    "name" : "test1",
    "attributes" : [ 
        {
            "name" : "x",
            "color" : "0xd79c9c",
            "_id" : ObjectId("5742be02289512cf98bf63e8")
        }, 
        {
            "name" : "y",
            "color" : "0xd79c9c",
            "_id" : ObjectId("5742be02289512cf98bf63e7")
        }, 
        {
            "name" : "z",
            "color" : "0xd79c9c",
            "_id" : ObjectId("5742be02289512cf98bf63e6")
        }
    ],
    "__v" : 6
}

我想更新所有文档,并为每个属性设置新字段。 所以我想运行一个查询来一次更新所有文档。我认为,这个查询会做

db.spaces.update({}, { $set: { "attributes.0.weight": 2 } }, {multi: true})

但是当我运行这个查询时,我得到一个错误:

“代码”:16837,
"errmsg" : "位置操作符没有找到 查询所需的匹配项。未扩展更新:attributes.$.weight"

我不明白为什么。 请帮忙

【问题讨论】:

  • 您需要在查询文档中包含数组字段才能使用位置运算符。
  • @chridam,我该怎么做?

标签: arrays mongodb updates


【解决方案1】:

位置运算符需要匹配,来自更新查询的匹配部分。

例如:

db.spaces.update({ "attributes.name": "x" }, { $set: { "attributes.0.weight": 2 } }, {multi: true})

这里更新操作的第一个参数将匹配数组attributes,其中任何元素都有一个属性name=="x",对于任何匹配条件的元素都可以使用位置运算符对其进行更新。

所以,因为name='x',在这种情况下,第一个匹配元素将是,

{
            "name" : "x",
            "color" : "0xd79c9c",
            "_id" : ObjectId("5742be02289512cf98bf63e8")
        }, 

它会得到更新。

现在根据您的问题,我了解到您希望更新文档,以便在每个文档中您的第一个元素 attribute 为 weight=2 获取新值。

你可以做类似的事情

db.spaces.update({ "attributes.name": { $regex: /^(?=[\S\s]{10,8000})[\S\s]*$/ } }, { $set: { "attributes.0.weight": 2 } }, {multi: true})

我们在这里做的是匹配数组属性中的所有元素。我们使用位置运算符来更新该数组的第一个元素

【讨论】:

【解决方案2】:

您需要在查询文档中包含数组字段才能使用 positional operator。

例如,如果您想更新第一个数组元素,即使用{ "attributes.name": "x" },那么您可以遵循以下模式:

db.spaces.update(
   { "attributes.name": "x" }, // <-- the array field must appear as part of the query document.
   { "$set": { "attributes.$.weight": 2 } },
   { "multi": true }
)

对于较新的 MongoDB 版本 3.2.X,您可以使用 updateMany() 方法根据上述过滤器更新集合中的多个文档。

【讨论】:

  • db.spaces.update({"attributes.name": { $exists: true }}, { $set: {"attributes.$.weight": 3}}, {multi: true }) 此查询仅更新数组中的第一项
  • 我需要为所有文档更新数组中的所有元素
  • @Gor 哦,我明白了,让我更新答案
  • @Gor 实际上存在提供解决方案的副本
  • @Gor 在这种情况下它不起作用的原因是位置 $ 运算符充当与查询文档匹配的 first 元素的占位符,并且不是数组中的所有元素。请参阅标记副本中的答案以获取解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多