英文:
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数组的循环 - 使用 
$objectToArray将values对象转换为键值对(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 })
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,
$mapto iterate loop ofparserErgebnisarray$objectToArrayconvertvaluesobject to an array in key-value (k-v) format$mapto iterate loop of the above converted (k-v) array, and returnkas it is andvvalue excludes the status property$arrayToObjectconverts values back to an object$mergeObjectsto merge current object and newly updatedvaluesobject
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 })
> The update() method depreciated, You can use updateMany() method.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论