本文介绍了条件匹配时更新嵌套数组中的多个项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几天前我开始学习 MongoDB,并试图围绕 update 运算符.

I started learning MongoDB a few days ago and trying to wrap my head around update operator.

这是我的文档结构:

db.records.insertMany([
  {
    name: 'first',
    subrecords: [
      { id: 1, isToBeUpdated: 0, value: 1 },
      { id: 2, isToBeUpdated: 0, value: 2 },
      { id: 3, isToBeUpdated: 0, value: 3 },
      { id: 4, isToBeUpdated: 1, value: 4 }
    ]
  },
  {
    name: 'second',
    subrecords: [
      { id: 22, isToBeUpdated: 1, value: 5 },
      { id: 23, isToBeUpdated: 0, value: 6 },
      { id: 24, isToBeUpdated: 1, value: 7 },
      { id: 25, isToBeUpdated: 0, value: 8 }
    ]
  }
])

我正在编写一个用于更新 subrecords 的命令.

I'm writing a command that is supposed to update subrecords.

我的意图是使用 isToBeUpdated 标志——如果它设置为 1 我们更新值字段,例如乘以 10.我们忽略带有 isToBeUpdated being 0 的项目.

My intent is to use isToBeUpdated flag — if it is set to 1 we update the value field, e.g. multiplying it by 10. We ignore items with isToBeUpdated being 0.

这是我编写的命令:

db.records.update(
  { 'subrecords.isToBeUpdated': 1 },
  { '$mul': { 'subrecords.$.value': 10 } },
  { multi: true }
)

我希望像这样更新 subrecords 数组的以下项目:

I expect to get the following items of subrecords array updated like this:

1. { id: 4, isToBeUpdated: 1, value: 40 }
2. { id: 22, isToBeUpdated: 1, value: 50 }
3. { id: 24, isToBeUpdated: 1, value: 70 }

但它只更新了 2 条记录,而不是 3 条.以下记录没有更新:

BUT it just updates 2 records, instead of 3. The following record is not updated:

3. { id: 24, isToBeUpdated: 1, value: 70 }

它是第二个项目, isToBeUpdated being 1 位于第二个文档的strong> subrecords collection — 似乎查询只更新任何文档中子记录数组的第一个匹配项.并忽略 first 之后的其他记录.

It is the second item with isToBeUpdated being 1 located in the second document's subrecords collection — seems like the query only updates the first matching item of subrecords array in any document. And ignores other records that are subsequent to first.

我尝试调整我的命令,将 [] 添加到 $(位置运算符):

I tried tweaking my command adding [] to $ (positional operator):

... { '$mul': { 'subrecords.$[].value': 10 } }, ...

但在这种情况下,任何文档的子记录数组中的每一项都会受到影响.

But in this case literally every single item in subrecords array of any document gets affected.

任何人都知道如何编写一个循环遍历所有记录并更新嵌套的每个项目的命令 subrecords array with isToBeUpdated 字段被设置为 1?

另外,我的想法是对的

  1. 那个 { multi: true } 意味着 records 集合中的所有记录文档都会受到影响?

  1. that { multi: true } implies that ALL record documents in records collection will be affected?

that { 'subrecords.isToBeUpdated': 1 }(查询部分)字面意思是我们只更新子记录 ARRAY 当一个文档在子记录中至少有一个项目 ARRAY WITH isToBeUpdated 字段是否设置为 1?

that { 'subrecords.isToBeUpdated': 1 } (query part) literally means that WE ONLY UPDATE subrecords ARRAY WHEN A DOCUMENT HAS AT LEAST ONE ITEM IN subrecords ARRAY WITH isToBeUpdated FIELD BEING SET TO 1?

推荐答案

解决方法是 arrayFilters

https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/#update-all-documents-that-match-arrayfilters-in-an-array

$[] 运算符有助于更新包含嵌入文档的数组.要访问嵌入文档中的字段,请使用 $[] 上的点表示法.

db.records.update(
  {},
  { '$mul': { 'subrecords.$[elem].value': 10 } },
  {
    multi: true,
    arrayFilters: [{ 'elem.isToBeUpdated': 1 }]
  }
)

这篇关于条件匹配时更新嵌套数组中的多个项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-21 14:45