MongoDB:取消设置数组中的嵌套字段

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

MongoDB: Unset nested field in array

问题

以下是翻译好的内容:

{
  "parserErgebnis": [
    {
      "values": {
        "prop1": {
          "status": "OK",
          "wert": "03.00"
        },
        "prop2": {
          "status": "OK",
          "wert": "1"
        }
      }
    },
    {
      "values": {
        "prop1": {
          "status": "OK",
          "wert": "03.00"
        },
        "prop5": {
          "status": "OK",
          "wert": "1"
        }
      }
    }
  ]
}
db.collection.update({},
{
  $unset: {
    "parserErgebnis.$[].values.prop1.status": 1
  }
},
{
  multi: true
})

你提到的通配符机制在 MongoDB 更新操作中不直接支持,但你可以使用代码来动态查找并删除所有字段中的 "status"。这需要在应用程序中编写逻辑来实现。

英文:

I have documents in a MongoDB that look like this:


  {
    "parserErgebnis": [
      {
        "values": {
          "prop1": {
            "status": "OK",
            "wert": "03.00"
          },
          "prop2": {
            "status": "OK",
            "wert": "1"
          }
        }
      },
      {
        "values": {
          "prop1": {
            "status": "OK",
            "wert": "03.00"
          },
          "prop5": {
            "status": "OK",
            "wert": "1"
          }
        }
      }
    ]
  }

I want to unset all fields 'status'. I know that an unset for a certain status would look like this:

db.collection.update({},
{
  $unset: {
    "parserErgebnis.$[].values.prop1.status": 1
  }
},
{
  multi: true
})

However, I want to remove all 'status' fields in one go (without even knowing how the props are basically named). I basically need a kind of wildcard mechanism like this (PSEUDOCODE NOT WORKING):

db.collection.update({},
{
  $unset: {
    "parserErgebnis.$[].values.*.status": 1
  }
},
{
  multi: true
})

Is there a way to get this working or is there an alternative approach? Thanks for your help

答案1

得分: 1

没有直接从动态属性中移除属性的方法,但是您可以从MongoDB 4.2开始使用聚合管道更新来实现:

  • 使用 $map 迭代 parserErgebnis 数组的循环
  • 使用 $objectToArrayvalues 对象转换为键值对(k-v)格式的数组
  • 使用 $map 迭代上述转换后的(k-v)数组的循环,并返回 k 不变,v 值不包括状态属性
  • 使用 $arrayToObject 将值转换回对象
  • 使用 $mergeObjects 合并当前对象和新更新的 values 对象
db.collection.update({},
[
  {
    $set: {
      parserErgebnis: {
        $map: {
          input: "$parserErgebnis",
          in: {
            $mergeObjects: [
              "$$this",
              {
                values: {
                  $arrayToObject: {
                    $map: {
                      input: { $objectToArray: "$$this.values" },
                      in: {
                        k: "$$this.k",
                        v: {
                          wert: "$$this.v.wert"
                        }
                      }
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
],
{ multi: true })

Playground

update() 方法已被弃用,您可以使用 updateMany() 方法。

英文:

There is no straight way to remove a property from a dynamic prop, but you can use update with aggregation pipeline starting from MongoDB 4.2,

  • $map to iterate loop of parserErgebnis array
  • $objectToArray convert values object to an array in key-value (k-v) format
  • $map to iterate loop of the above converted (k-v) array, and return k as it is and v value excludes the status property
  • $arrayToObject converts values back to an object
  • $mergeObjects to merge current object and newly updated values object
db.collection.update({},
[
  {
    $set: {
      parserErgebnis: {
        $map: {
          input: "$parserErgebnis",
          in: {
            $mergeObjects: [
              "$$this",
              {
                values: {
                  $arrayToObject: {
                    $map: {
                      input: { $objectToArray: "$$this.values" },
                      in: {
                        k: "$$this.k",
                        v: {
                          wert: "$$this.v.wert"
                        }
                      }
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
],
{ multi: true })

Playrgound

> The update() method depreciated, You can use updateMany() method.

huangapple
  • 本文由 发表于 2023年6月22日 00:48:59
  • 转载请务必保留本文链接:https://go.coder-hub.com/76525513.html
匿名

发表评论

匿名网友

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

确定