MongoDB 更新匹配 _id 及数组内多个条件的数组元素

huangapple go评论59阅读模式
英文:

MongoDB update an array element matching _id and multiple conditions within the array

问题

我有一个 MongoDB 集合如下:

集合:

[
  {
    "_id": ObjectId("64390a7196f544082a671469"),
    "name": "Sydney",
    "issues": [
      {"vol": "2", "num": "1", "freq": 5},
      {"vol": "1", "num": "2", "freq": 7}
    ]
  },
  {
    "_id": ObjectId("64390a8796f544082a67146a"),
    "name": "Canton",
    "issues": [
      {"vol": "2", "num": "2", "freq": 9},
      {"vol": "1", "num": "3", "freq": 9},
      {"vol": "2", "num": "1", "freq": 11}
    ]
  }
]

我想要更新匹配 _idissues.volissues.num 值的 issues.freq 字段。

具体来说,如果:

  1. _id:ObjectId("64390a8796f544082a67146a"),
  2. issue.vol:"2"
  3. issue.num:"1"

issue.freq 将更新为 45(从现有值 11)。

这是我目前得到的查询:

查询:

db.collection.update({
  "_id": ObjectId("64390a8796f544082a67146a"),
  "issues.vol": "2",
  "issues.num": "1"
},
{
  "$set": {
    "issues.$.freq": 45
  }
})

问题是,它更新了 ("_id": ObjectId("64390a8796f544082a67146a"), "issues.vol": "2""issues.num": "2") 的值,而不是 ("_id": ObjectId("64390a8796f544082a67146a"), "issues.vol": "2""issues.num": "1")。我做错了什么?

查询后的结果集:

[
  {
    "_id": ObjectId("64390a7196f544082a671469"),
    "issues": [
      {"freq": 5, "num": "1", "vol": "2"},
      {"freq": 7, "num": "2", "vol": "1"}
    ],
    "name": "Sydney"
  },
  {
    "_id": ObjectId("64390a8796f544082a67146a"),
    "issues": [
      {"freq": 45, "num": "2", "vol": "2"},
      {"freq": 9, "num": "3", "vol": "1"},
      {"freq": 11, "num": "1", "vol": "2"}
    ],
    "name": "Canton"
  }
]

Mongo playground 链接

非常感谢您阅读到这里。如果您对此有所思考,我也想表示感谢。

英文:

I have a MongoDB collections as:

Collection:

<!-- language: lang-json -->
[
{
"_id": ObjectId("64390a7196f544082a671469"),
"name": "Sydney",
"issues": [
{"vol": "2", "num": "1", "freq": 5},
{"vol": "1", "num": "2", "freq": 7}
]
},
{
"_id": ObjectId("64390a8796f544082a67146a"),
"name": "Canton",
"issues": [
{"vol": "2", "num": "2", "freq": 9},
{"vol": "1", "num": "3", "freq": 9},
{"vol": "2", "num": "1", "freq": 11}
]
}
]

I want to update issues.freq field matching with the _id, issues.vol and issues.num values.

To be specific, if

  1. _id:ObjectId(&quot;64390a8796f544082a67146a&quot;),
  2. issue.vol:&quot;2&quot; and
  3. issue.num:&quot;1&quot;

issue.freq will be updated to 45 (from existing value of 11).

Here is the query that I have arrived so far:

Query:

db.collection.update({
  &quot;_id&quot;: ObjectId(&quot;64390a8796f544082a67146a&quot;),
  &quot;issues.vol&quot;: &quot;2&quot;,
  &quot;issues.num&quot;: &quot;1&quot;
},
{
  &quot;$set&quot;: {
    &quot;issues.$.freq&quot;: 45
  }
})

The problem is, it updates the value for (&quot;_id&quot;: ObjectId(&quot;64390a8796f544082a67146a&quot;), &quot;issues.vol&quot;: &quot;2&quot; and &quot;issues.num&quot;: &quot;2&quot;) instead of (&quot;_id&quot;: ObjectId(&quot;64390a8796f544082a67146a&quot;), &quot;issues.vol&quot;: &quot;2&quot; and &quot;issues.num&quot;: &quot;1&quot;). What am I doing wrong?

Result set (after my query above):

<!-- language: lang-json -->
[
{
"_id": ObjectId("64390a7196f544082a671469"),
"issues": [
{"freq": 5, "num": "1", "vol": "2"},
{"freq": 7, "num": "2","vol": "1"}
],
"name": "Sydney"
},
{
"_id": ObjectId("64390a8796f544082a67146a"),
"issues": [
{"freq": 45, "num": "2", "vol": "2"},
{"freq": 9, "num": "3", "vol": "1"},
{"freq": 11, "num": "1", "vol": "2"}
],
"name": "Canton"
}
]

Mongo playground link

So many thanks for reading this far. I would also like to extend my gratitude if you have given some thoughts on this.

答案1

得分: 1

使用定位过滤运算符 $[<identifier>] 与数组中特定元素进行更新。

db.collection.update({
  "_id": ObjectId("64390a8796f544082a67146a"),
  "issues.vol": "2",
  "issues.num": "1"
},
{
  "$set": {
    "issues.$[i].freq": 45
  }
},
{
  arrayFilters: [
    {
      "i.vol": "2",
      "i.num": "1"
    }
  ]
})

演示 @ Mongo Playground

英文:

Works with positional filtered operator $[&lt;identifier&gt;] to update specific element(s) in an array.

db.collection.update({
  &quot;_id&quot;: ObjectId(&quot;64390a8796f544082a67146a&quot;),
  &quot;issues.vol&quot;: &quot;2&quot;,
  &quot;issues.num&quot;: &quot;1&quot;
},
{
  &quot;$set&quot;: {
    &quot;issues.$[i].freq&quot;: 45
  }
},
{
  arrayFilters: [
    {
      &quot;i.vol&quot;: &quot;2&quot;,
      &quot;i.num&quot;: &quot;1&quot;
    }
  ]
})

Demo @ Mongo Playground

答案2

得分: 0

相应的 PyMongo 查询:

如果对于使用 PyMongo 有所帮助(注意:MongoDB 的 arrayFilters 在 PyMongo 中变为 array_filters):

import bson

edvol= "2"
ednum= "1"
per_col.update_one(
    {
        '_id': bson.ObjectId("64390a8796f544082a67146a"),
        "issues.vol": edvol,
        "issues.num": ednum
    }, 
    {'$set': {"issues.$[i].freq": 45}}, 
    upsert=False,
    array_filters=[{'i.vol': edvol, 'i.num': ednum}]
)
英文:

Corresponding PyMongo query:

If it helps anyone working with PyMongo (Note: arrayFilters of MongoDB becomes array_filters in PyMongo):

import bson

edvol= &quot;2&quot;
ednum= &quot;1&quot;
per_col.update_one(
    {
        &#39;_id&#39;: bson.ObjectId(&quot;64390a8796f544082a67146a&quot;),
        &quot;issues.vol&quot;: edvol,
        &quot;issues.num&quot;: ednum
    }, 
    {&#39;$set&#39;: {&quot;issues.$[i].freq&quot;: 45}}, 
    upsert=False,
    array_filters=[{&#39;i.vol&#39;: edvol, &#39;i.num&#39;: ednum}]
)

huangapple
  • 本文由 发表于 2023年4月17日 21:15:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76035581.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定