位置运算符目标是“ findoneandupdate”更新查询中数组字段的错误元素

发布于 2025-02-08 20:43:38 字数 1707 浏览 2 评论 0原文

我有一个文档

{
    "_id": "62ac8190ddb08e6ee5f2c7dd",
    "status": "NEW",
    "vendor": "62ac8171ddb08e6ee5f2c7ca",
    "productsInOrder": [
      {
        "product": "62ac8176ddb08e6ee5f2c7cd",
        "amount": 1
      },
      {
        "product": "62ac8181ddb08e6ee5f2c7d0",
        "amount": 1
      }
    ],
    "createdAt": "2022-06-17T13:28:48.815Z",
    "updatedAt": "2022-06-17T13:39:44.073Z",
    "orderNumber": 82,
    "__v": 2
  }

文档中productiNOrder数组的第二个元素。

db.collection.findOneAndUpdate({
  status: "NEW",
  vendor: "62ac8171ddb08e6ee5f2c7ca",
  "productsInOrder.product": "62ac8181ddb08e6ee5f2c7d0",
  "productsInOrder.amount": {
    $lte: 3
  },
  
},
{
  $inc: {
    "productsInOrder.$.amount": 1
  }
})

和一个查询来更新 数量增加了1

{
    "_id": "62ac8190ddb08e6ee5f2c7dd",
    "status": "NEW",
    "vendor": "62ac8171ddb08e6ee5f2c7ca",
    "productsInOrder": [
      {
        "product": "62ac8176ddb08e6ee5f2c7cd",
        "amount": 1
      },
      {
        "product": "62ac8181ddb08e6ee5f2c7d0",
        "amount": 2 // increased by 1
      }
    ],
    "createdAt": "2022-06-17T13:28:48.815Z",
    "updatedAt": "2022-06-17T13:39:44.073Z",
    "orderNumber": 82,
    "__v": 2
  }

,而是具有ID 的产品增加了,“ 62AC8176DDB08E6EE5F2C7CD”被更新如下所示。 //mongoplayground.net/p/ueu5lcavjd0

我不明白为什么位置操作员选择数组的第一个元素,而不是查找Query中指定的元素,

我该如何更新相同iD id id id /code>在“ productinorder.product”中查找查询中指定的?

I have a document

{
    "_id": "62ac8190ddb08e6ee5f2c7dd",
    "status": "NEW",
    "vendor": "62ac8171ddb08e6ee5f2c7ca",
    "productsInOrder": [
      {
        "product": "62ac8176ddb08e6ee5f2c7cd",
        "amount": 1
      },
      {
        "product": "62ac8181ddb08e6ee5f2c7d0",
        "amount": 1
      }
    ],
    "createdAt": "2022-06-17T13:28:48.815Z",
    "updatedAt": "2022-06-17T13:39:44.073Z",
    "orderNumber": 82,
    "__v": 2
  }

And a query to update second element of productsInOrder array in the document

db.collection.findOneAndUpdate({
  status: "NEW",
  vendor: "62ac8171ddb08e6ee5f2c7ca",
  "productsInOrder.product": "62ac8181ddb08e6ee5f2c7d0",
  "productsInOrder.amount": {
    $lte: 3
  },
  
},
{
  $inc: {
    "productsInOrder.$.amount": 1
  }
})

After executing the update query I expect product with id "62ac8181ddb08e6ee5f2c7d0" to be updated, i.e it's amount increased by 1

{
    "_id": "62ac8190ddb08e6ee5f2c7dd",
    "status": "NEW",
    "vendor": "62ac8171ddb08e6ee5f2c7ca",
    "productsInOrder": [
      {
        "product": "62ac8176ddb08e6ee5f2c7cd",
        "amount": 1
      },
      {
        "product": "62ac8181ddb08e6ee5f2c7d0",
        "amount": 2 // increased by 1
      }
    ],
    "createdAt": "2022-06-17T13:28:48.815Z",
    "updatedAt": "2022-06-17T13:39:44.073Z",
    "orderNumber": 82,
    "__v": 2
  }

but instead product with id "62ac8176ddb08e6ee5f2c7cd" gets updated as seen here https://mongoplayground.net/p/UEU5LCAVjD0

I don't understand why positional operator selects the first element of the array instead of the element specified in find query

How can I update array element of the same id that is specified in find query in `"productsInOrder.product"?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉风有信 2025-02-15 20:43:38

请参阅 docs

在多个数组字段过滤时,位置$更新操作员行为歧义。

服务器执行更新方法时,它首先运行查询
确定您要更新的文档。如果更新过滤器
多个数组字段上的文档,随后的调用
位置$更新操作员并不总是更新所需的
位于阵列中。

由于您的查询指定productiNorder.productproductiNOrder.amount.amount,因此被认为是在多个数组字段上过滤。在您的情况下,您应该使用 $ elemmatch 而不是

db.collection.update({
  status: "NEW",
  vendor: "62ac8171ddb08e6ee5f2c7ca",
  productsInOrder: {
    $elemMatch: {
      product: "62ac8181ddb08e6ee5f2c7d0",
      amount: {
        $lte: 3
      }
    }
  }
},
{
  $inc: {
    "productsInOrder.$.amount": 1
  }
})

mongoplayground

Refer to the docs:

The positional $ update operator behaves ambiguously when filtering on multiple array fields.

When the server executes an update method, it first runs a query to
determine which documents you want to update. If the update filters
documents on multiple array fields, the subsequent call to the
positional $ update operator doesn't always update the required
position in the array.

Since your query specify productsInOrder.product and productsInOrder.amount, it's considered to be filtering on multiple array fields. In your case, you should use $elemMatch instead:

db.collection.update({
  status: "NEW",
  vendor: "62ac8171ddb08e6ee5f2c7ca",
  productsInOrder: {
    $elemMatch: {
      product: "62ac8181ddb08e6ee5f2c7d0",
      amount: {
        $lte: 3
      }
    }
  }
},
{
  $inc: {
    "productsInOrder.$.amount": 1
  }
})

MongoPlayground

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文