【问题标题】:MongoDB: Push to a nested array or update the existing array elementMongoDB:推送到嵌套数组或更新现有数组元素
【发布时间】:2022-01-04 15:58:13
【问题描述】:

我有一份格式如下的文件:

// Document
{
   _id: ObjectId("67dc90594947be000838f7a7"),
   persons: [
        {
           personId: "61cd90594947be000838f7c1",
           name: "John Doe"
           employment: [
               {
                  employmentId: "61cd9059494abe000838f7c8",
                  type: "Full time",
                  salary: 1010101
               }
           ]
        },
        {
           personId: "61cd90594947be000838f7c2",
           name: "Jane Austin"
           employment: [
               {
                  employmentId: "61cd9059494abe000838f7c8",
                  type: "Part time",
                  salary: 11011111
               }
           ]
        },
   ]
}

我需要一个查询,如果就业的employmentId 匹配,则更新persons 内的现有employment,或者将新元素推送到数组。

例如

案例一:更新就业情况

// update payload
// This employment id is the first employment of John Doe
// So the first employment will be updated
{
    personId: "61cd90594947be000838f7c1",
    employmentId: "61cd9059494abe000838f7c8",
    frequency: "weekly"
}
// The updated document
{
   _id: ObjectId("67dc90594947be000838f7a7"),
   persons: [
        {
           personId: "61cd90594947be000838f7c1",
           name: "John Doe"
           employment: [
               // This is updated employment
               {
                  employmentId: "61cd9059494abe000838f7c8",
                  type: "Full time",
                  salary: 1010101,
                  frequency: "weekly"
               }
           ]
        },
        {
           personId: "61cd90594947be000838f7c2",
           name: "Jane Austin"
           employment: [
               {
                  employmentId: "61cd9059494abe000838f7c8",
                  type: "Part time",
                  salary: 11011111
               }
           ]
        },
   ]
}

案例二:推新就业

// update payload
// This employment id is not in John Doe
// So the data will be pushed to array
{
    personId: "61cd90594947be000838f7c1",
    employmentId: "61cd9059494abe000738f7c1",
    frequency: "weekly"
}
// The updated document
{
   _id: ObjectId("67dc90594947be000838f7a7"),
   persons: [
        {
           personId: "61cd90594947be000838f7c1",
           name: "John Doe"
           employment: [
               {
                  employmentId: "61cd9059494abe000838f7c8",
                  type: "Full time",
                  salary: 1010101
               },
               /// This is newly added employment
               {
                  employmentId: "61cd9059494abe000738f7c1",
                  frequency: "weekly"
               }
           ]
        },
        {
           personId: "61cd90594947be000838f7c2",
           name: "Jane Austin"
           employment: [
               {
                  employmentId: "61cd9059494abe000838f7c8",
                  type: "Part time",
                  salary: 11011111
               }
           ]
        },
   ]
}

对于非嵌套数组,我得到了this answer

【问题讨论】:

    标签: node.js arrays mongodb mongodb-query aggregation-framework


    【解决方案1】:

    同样,该方法仍然类似于上一个问题的更新,我们必须迭代每个数组并确定元素是否匹配。

    请注意,此答案不处理问题中不需要的情况 #3,即人不存在的情况。根据输入,我认为此人的存在是合理的。

    const input = {
        personId: "61cd90594947be000838f7c1",
        employmentId: "61cd9059494abe000738f7c1",
        frequency: "weekly"
    };
    
    const employmentInput = {
        employmentId: "61cd9059494abe000738f7c1",
        frequency: "weekly"
    };
    
    db.collection.update({},
    [
      {
        $set: {
          persons: {
            $map: {
              input: "$persons",
              as: "person",
              in: {
                $cond: [
                  {
                    $eq: [
                      input.personId,
                      "$$person.personId"
                    ]
                  },
                  {
                    $mergeObjects: [
                      "$$person",
                      {
                        employment: {
                          $cond: [
                            {
                              $in: [
                                input.employmentId,
                                "$$person.employment.employmentId"
                              ]
                            },
                            {
                              $map: {
                                input: "$$person.employment",
                                as: "employment",
                                in: {
                                  $cond: [
                                    {
                                      $eq: [
                                        input.employmentId,
                                        "$$employment.employmentId"
                                      ]
                                    },
                                    {
                                      $mergeObjects: [
                                        "$$employment",
                                        employmentInput
                                      ]
                                    },
                                    "$$employment"
                                  ]
                                }
                              }
                            },
                            {
                              $concatArrays: [
                                "$$person.employment",
                                [
                                  employmentInput
                                ]
                              ]
                            }
                          ]
                        }
                      }
                    ]
                  },
                  "$$person"
                ]
              }
            }
          }
        }
      }
    ])
    

    Mongo Playground

    【讨论】:

    • 感谢您的回答!如果您有兴趣,请查看我的另一个问题:D。 stackoverflow.com/questions/70580173/…
    • 您使用的是哪个 Mongo 版本?这个稍微复杂一些,但可以根据版本进行简化。
    • 我使用的是 4.4.10 版本。
    猜你喜欢
    • 2014-07-29
    • 2016-02-25
    • 2014-07-29
    • 2022-01-22
    • 1970-01-01
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多