mongodb Mongo更新数组并跳过空字段

hk8txs48  于 2022-12-18  发布在  Go
关注(0)|答案(1)|浏览(202)

我正在处理一个Mongo updateMany()查询。
以下是我收藏的一份文件的浓缩示例:

{
    "CurrentVersion": 3,
    "EntryHistory": [
        {
            "State": 0,
            "ProposalPlan": [
                {
                    "Description": "Test",
                    "State": 1,
                    "Proposals": [
                        {
                            "Subject": "Test",
                            "Body": "Test",
                            "Urls": [
                                {
                                    "Description": "Link text",
                                    "Address": "https://examplelink.com"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

请假设我的测试数据只是显示结构,而不是集合和数组的实际大小。
如何编写updateMany()查询,使其在遇到文档中的空字段时不会出错?我只希望它在出现问题时继续更新文档。
下面是我编写的查询:

db.collectionName.updateMany(
    { "ProposalPlan.State": 1 },
    {
        $set: {
            "ProposalPlan.State": 3,
            "ProposalPlan.Proposals.10.Urls.0.Address": "https://newlinkexample.com"
        }
    }
);

我的问题是,当我运行此查询时,一些满足筛选条件的文档“损坏”,并且具有空的或不存在的Proposals和/或空的或不存在的URL,因此我遇到了诸如“MongoServerError:无法在元素{Urls:空}"。
我还尝试过将上面的查询 Package 在try catch中,因为我希望它在文档抛出错误后继续执行,但我发现它不是这样工作的。
我试图添加到过滤器,使我甚至不试图更新损坏的文档开始:

db.collectionName.updateMany(
    { "ProposalPlan.State": 1, "ProposalPlan.Proposals.10.Urls.0.Address": { $ne: null } },
    {
        $set: {
            "ProposalPlan.State": 3,
            "ProposalPlan.Proposals.10.Urls.0.Address": "https://newlinkexample.com"
        }
    }
);


但是到目前为止,这些方法都不起作用,上面的额外过滤器不会抛出错误,但不会更新任何内容,当我尝试将过滤器与findOne()一起使用时,它只是无限地搜索,而不是从ProposalPlan.State为1且ProposalPlan.Proposals.10.Urls.0.Address不为空的许多记录中抓取一条。

osh3o9ms

osh3o9ms1#

这是一个选项:

db.collection.update({},
[
 {
  $set: {
  "EntryHistory": {
    "$map": {
      "input": "$EntryHistory",
      "as": "e",
      "in": {
        "$mergeObjects": [
          "$$e",
          {
            "ProposalPlan": {
              "$map": {
                "input": "$$e.ProposalPlan",
                "as": "p",
                "in": {
                  "$mergeObjects": [
                    "$$p",
                    {
                      "$cond": {
                        "if": {
                          "$eq": [
                            "$$p.State",
                            1
                          ]
                        },
                        "then": {
                          State: 3,
                          Proposals: {
                            "$map": {
                              "input": "$$p.Proposals",
                              "as": "r",
                              "in": {
                                "$mergeObjects": [
                                  "$$r",
                                  {
                                    "$cond": {
                                      "if": {
                                        "$eq": [
                                          {
                                            "$indexOfArray": [
                                              "$$p.Proposals",
                                              "$$r"
                                            ]
                                          },
                                          0// Index of Proposals
                                          
                                        ]
                                      },
                                      "then": {
                                        "Urls": {
                                          "$map": {
                                            "input": "$$r.Urls",
                                            "as": "u",
                                            "in": {
                                              "$mergeObjects": [
                                                "$$u",
                                                {
                                                  "$cond": {
                                                    "if": {
                                                      $and: [
                                                        {
                                                          "$eq": [
                                                            {
                                                              "$indexOfArray": [
                                                                "$$r.Urls",
                                                                "$$u"
                                                              ]
                                                            },
                                                            2// Index of Urls
                                                            
                                                          ]
                                                        },
                                                        {
                                                          "$ne": [
                                                            "$$u.Address",
                                                            null
                                                          ]
                                                        }
                                                      ]
                                                    },
                                                    "then": {
                                                      Address: "Example new link"
                                                    },
                                                    "else": {}
                                                  }
                                                }
                                              ]
                                            }
                                          }
                                        }
                                      },
                                      "else": {}
                                    }
                                  }
                                ]
                              }
                            }
                          }
                        },
                        "else": {}
                      }
                    }
                  ]
                }
              }
            }
          }
          ]
         }
       }
      }
     }
    }
   ])

解释:
它将更新:

"ProposalPlan.State": 3,
        "ProposalPlan.Proposals.0.Urls.2.Address": "new value"

(将Peoposals.10更改为0,因为示例太大...)
但如果(“提案计划.Proposals.0.Urls.2.Address”== null),则它将仅更新:

"ProposalPlan.State": 3


Playground

相关问题