将所有字段设置为false的所有字段,然后将第二个字段设置为单个查询中的true

发布于 2025-02-12 10:19:33 字数 1268 浏览 4 评论 0原文

假设我有以下文档结构。

[
  {
    "_id": 1,
    "depots": [
      {
        "_id": 1,
        "isFavourite": true
      },
      {
        "_id": 2,
        "isFavourite": false
      },
      {
        "_id": 3,
        "isFavourite": true
      },
      {
        "_id": 4,
        "isFavourite": false
      }
    ]
  }
]

我想编写一个单个更新查询哪个用_id滤除文档的过滤:1,并首先设置每个isfavurite值值 false < /code>,然后将第二个ISFAVURITE值(或任何指定的索引)设置为true

结果文档应该看起来像这样。

[
  {
    "_id": 1,
    "depots": [
      {
        "_id": 1,
        "isFavourite": false
      },
      {
        "_id": 2,
        "isFavourite": true
      },
      {
        "_id": 3,
        "isFavourite": false
      },
      {
        "_id": 4,
        "isFavourite": false
      }
    ]
  }
]

我尝试的是:

db.collection.update({
  _id: 1
},
[
  {
    "$set": {
      "depots.isFavourite": false
    }
  },
  {
    "$set": {
      "depots.2.isFavourite": true
    }
  }
])

奇怪的是,这行不通。有关此查询的结果,请参见链接的操场。

mongo Playground

Suppose I have the following the document structure.

[
  {
    "_id": 1,
    "depots": [
      {
        "_id": 1,
        "isFavourite": true
      },
      {
        "_id": 2,
        "isFavourite": false
      },
      {
        "_id": 3,
        "isFavourite": true
      },
      {
        "_id": 4,
        "isFavourite": false
      }
    ]
  }
]

I want to write a single update query which filters for the document with _id: 1 and first sets every isFavourite value to false and then sets the second isFavourite value (or any specified index) to true.

The resulting document should look like this.

[
  {
    "_id": 1,
    "depots": [
      {
        "_id": 1,
        "isFavourite": false
      },
      {
        "_id": 2,
        "isFavourite": true
      },
      {
        "_id": 3,
        "isFavourite": false
      },
      {
        "_id": 4,
        "isFavourite": false
      }
    ]
  }
]

What I tried:

db.collection.update({
  _id: 1
},
[
  {
    "$set": {
      "depots.isFavourite": false
    }
  },
  {
    "$set": {
      "depots.2.isFavourite": true
    }
  }
])

Yet strangely this does not work. See the linked playground for the result of this query.

Mongo Playground

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

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

发布评论

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

评论(2

蓝礼 2025-02-19 10:19:33

仅当更新不是管道时,使用索引作为点表示法可行。

一种选项是使用$降低“重建”数组,这使我们可以使用当前构建的数组的大小来查找所需索引的项目,然后$ MergeObjects 具有更新的字段和值:

db.collection.update(
{_id: 1},
[
  {$set: {"depots.isFavourite": false}},
  {$set: {
      depots: {
        $reduce: {
          input: "$depots",
          initialValue: [],
          in: {
            $concatArrays: [
              "$value",
              [
                {$cond: [
                    {$eq: [{$size: "$value"}, requestedIndex]},
                    {$mergeObjects: ["$this", {isFavourite: true}]},
                    "$this"
                  ]
                }
              ]
            ]
          }
        }
      }
    }
  }
])

请参阅游乐场示例

Using the index as a dot notation only works when the update is not a pipeline.

One option is to "rebuild" the array using $reduce, which allow us to use the size of the currently built array to find the item with the requested index, and then $mergeObjects it with the updated field and value:

db.collection.update(
{_id: 1},
[
  {$set: {"depots.isFavourite": false}},
  {$set: {
      depots: {
        $reduce: {
          input: "$depots",
          initialValue: [],
          in: {
            $concatArrays: [
              "$value",
              [
                {$cond: [
                    {$eq: [{$size: "$value"}, requestedIndex]},
                    {$mergeObjects: ["$this", {isFavourite: true}]},
                    "$this"
                  ]
                }
              ]
            ]
          }
        }
      }
    }
  }
])

See how it works on the playground example

情栀口红 2025-02-19 10:19:33

您对此有何看法:

db.collection.update({
  _id: 1
},
{
  "$set": {
    "depots.$[y].isFavourite": false,
    "depots.$[x].isFavourite": true
  }
},
{
  arrayFilters: [
    {
      "x._id": 2
    },
    {
      "y._id": {
        $ne: 2
      }
    }
  ],
  "multi": true
})

解释:

设置两个ArrayFilters X&amp; y匹配两个条件...

Playground

What do you think about this:

db.collection.update({
  _id: 1
},
{
  "$set": {
    "depots.$[y].isFavourite": false,
    "depots.$[x].isFavourite": true
  }
},
{
  arrayFilters: [
    {
      "x._id": 2
    },
    {
      "y._id": {
        $ne: 2
      }
    }
  ],
  "multi": true
})

Explained:

Set two arrayFilters x & y that match the two conditions ...

Playground

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