如何根据特定条件更新文档中的2个数组元素

时间:2019-07-01 12:04:50

标签: arrays node.js mongodb updates

我有一个包含2个数组的文档,我试图使用$elemMatch同时基于某种条件更新两个数组的特定数组元素。

查询

targetManagementSchema.findOneAndUpdate({
     franchiseeId : franchiseeId,
     'yearlyTarget.year': 2019,
     'quarterlyTarget': {
        $elemMatch: {
            'quarter.from': 7,
            'quarter.to': 9
        }
      },
     'monthlyTarget': {
        $elemMatch: {
           'month': 7
        }
      }
    }, {
    $set: {
        'yearlyTarget.targetAchieved': 101540.7,
        'quarterlyTarget.$.targetAchieved': 101540.7,
        'monthlyTarget.$.targetAchieved': 101540.7
    }
}, (err, updatedTargetRes) => {
      if (err) {
         console.log("error in updating targetsAchieved " + err);
      } else if (updatedTargetRes != null && updatedTargetRes != '') {
         console.log(updatedTargetRes + " :updatedTargetRes");
      } else {
         console.log("target not updated");
      }
})

更新前的文件

{
    "_id": ObjectId("5cc6d6151b74b719acd36eaf"),
    "quarterlyTarget": [
        {
            "quarter": {
                "from": 4,
                "to": 6
            },
            "target": 47000,
            "targetAchieved": 0
        },
        {
            "quarter": {
                "from": 7,
                "to": 9
            },
            "target": 51200,
            "targetAchieved": 0
        },
        {
            "quarter": {
                "from": 10,
                "to": 12
            },
            "target": 64000,
            "targetAchieved": 0
        },
        {
            "quarter": {
                "from": 1,
                "to": 3
            },
            "target": 35000,
            "targetAchieved": 0
        }
    ],
    "monthlyTarget": [
        {
            "month": 1,
            "target": 10000,
            "targetAchieved": 0
        },
        {
            "month": 2,
            "target": 10000,
            "targetAchieved": 0
        },
        {
            "month": 3,
            "target": 15000,
            "targetAchieved": 0
        },
        {
            "month": 4,
            "target": 15500,
            "targetAchieved": 0
        },
        {
            "month": 5,
            "target": 15500,
            "targetAchieved": 0
        },
        {
            "month": 6,
            "target": 16000,
            "targetAchieved": 0
        },
        {
            "month": 7,
            "target": 16200,
            "targetAchieved": 0
        },
        {
            "month": 8,
            "target": 17000,
            "targetAchieved": 0
        },
        {
            "month": 9,
            "target": 18000,
            "targetAchieved": 0
        },
        {
            "month": 10,
            "target": 19000,
            "targetAchieved": 0
        },
        {
            "month": 11,
            "target": 20000,
            "targetAchieved": 0
        },
        {
            "month": 12,
            "target": 19000,
            "targetAchieved": 0
        }
    ],
    "franchiseeId": "5c42bd6085edaa215cba5a21",
    "yearlyTarget": {
        "year": 2019,
        "target": 197200,
        "targetAchieved": 0
    },
    "offer": null,
    "status": "1",
    "createdAt": ISODate("2019-04-29T10:46:45.643Z"),
    "__v": 0
}

更新后的文档

{
    "_id": ObjectId("5cc6d6151b74b719acd36eaf"),
    "quarterlyTarget": [
        {
            "quarter": {
                "from": 4,
                "to": 6
            },
            "target": 47000,
            "targetAchieved": 0
        },
        {
            "quarter": {
                "from": 7,
                "to": 9
            },
            "target": 51200,
            "targetAchieved": 101540.7 //updates successfully
        },
        {
            "quarter": {
                "from": 10,
                "to": 12
            },
            "target": 64000,
            "targetAchieved": 0
        },
        {
            "quarter": {
                "from": 1,
                "to": 3
            },
            "target": 35000,
            "targetAchieved": 0
        }
    ],
    "monthlyTarget": [
        {
            "month": 1,
            "target": 10000,
            "targetAchieved": 0
        },
        {
            "month": 2,
            "target": 10000,
            "targetAchieved": 101540.7 //updates here, which is wrong
        },
        {
            "month": 3,
            "target": 15000,
            "targetAchieved": 0
        },
        {
            "month": 4,
            "target": 15500,
            "targetAchieved": 0
        },
        {
            "month": 5,
            "target": 15500,
            "targetAchieved": 0
        },
        {
            "month": 6,
            "target": 16000,
            "targetAchieved": 0
        },
        {
            "month": 7,
            "target": 16200,
            "targetAchieved": 0 //must update the value 101540.7 here
        },
        {
            "month": 8,
            "target": 17000,
            "targetAchieved": 0
        },
        {
            "month": 9,
            "target": 18000,
            "targetAchieved": 0
        },
        {
            "month": 10,
            "target": 19000,
            "targetAchieved": 0
        },
        {
            "month": 11,
            "target": 20000,
            "targetAchieved": 0
        },
        {
            "month": 12,
            "target": 19000,
            "targetAchieved": 0
        }
    ],
    "franchiseeId": "5c42bd6085edaa215cba5a21",
    "yearlyTarget": {
        "year": 2019,
        "target": 197200,
        "targetAchieved": 101540.7
    },
    "offer": null,
    "status": "1",
    "createdAt": ISODate("2019-04-29T10:46:45.643Z"),
    "__v": 0
}

它采用第一个匹配项的索引,即1数组的quarterlyTarget并将其应用于monthlyTarget数组,而不是根据我指定的条件获取索引。因此,更新了monthlyTarget数组的错误索引。

我知道可以使用arrayFilters来实现,我也做到了。但是我正在使用的mongodb版本是3.2,不幸的是我无法升级它,因此,我需要使用3.2支持的方法。

2 个答案:

答案 0 :(得分:1)

viewmultiplrarrayupdate: (callback) => {
    maultipleArrayUpdate.findOneAndUpdate({
      "franchiseeId": '5c42bd6085edaa215cba5a21',
      'yearlyTarget.year': 2019,
      'quarterlyTarget': {
        $elemMatch: {
          'quarter.from': 7,
          'quarter.to': 9
        }
      }
    },
      {
        $set: {
          'yearlyTarget.targetAchieved': 101540.7,
          'quarterlyTarget.$.targetAchieved': 101540.7,
        }
      }
      , (err, updatedTargetResponse) => {
        if (err) {
          callback(err, null)
        }
        else {
          maultipleArrayUpdate.findOneAndUpdate({
            "franchiseeId": '5c42bd6085edaa215cba5a21',
            'yearlyTarget.year': 2019,
            'monthlyTarget': {
              $elemMatch: {
                'month': 7
              }
            }
          }, { 'monthlyTarget.$.targetAchieved': 101540.7 }, (error, updatedTargetRes) => {
            if (error) {
              callback(error, null)
            }
            else {
              callback(null, "successfully updated")
            }
          })
        }
      })
  },

答案 1 :(得分:0)

好吧,您错过了{upsert:true}

我在Mongo Editor上运行了该查询,并且该查询有效。让我知道这是否适合您(也知道我只使用了部分查找查询,因为只有一个文档。您可以继续使用完整的查找块。我的重点是更新文档)

db.user_test.findOneAndUpdate(

    {franchiseeId: "5c42bd6085edaa215cba5a21", "yearlyTarget.year":2019, "quarterlyTarget": {
        $elemMatch: {
            "quarter.from": 7,
            "quarter.to": 9
        }
      }},

      {
    $set: {
        'yearlyTarget.targetAchieved': 101540.7,
        'quarterlyTarget.$.targetAchieved': 101540.7,
        'monthlyTarget.$.targetAchieved': 101540.7
    }
}, 

{upsert:true})

这是我更新后返回的文档

{
    "_id" : ObjectId("5d1a1212a9eea913c2b8229a"),
    "quarterlyTarget" : [
        {
            "quarter" : {
                "from" : 4,
                "to" : 6
            },
            "target" : 47000,
            "targetAchieved" : 0
        },
        {
            "quarter" : {
                "from" : 7,
                "to" : 9
            },
            "target" : 51200,
            "targetAchieved" : 101540.7
        },
        {
            "quarter" : {
                "from" : 10,
                "to" : 12
            },
            "target" : 64000,
            "targetAchieved" : 0
        },
        {
            "quarter" : {
                "from" : 1,
                "to" : 3
            },
            "target" : 35000,
            "targetAchieved" : 0
        }
    ],
    "monthlyTarget" : [
        {
            "month" : 1,
            "target" : 10000,
            "targetAchieved" : 0
        },
        {
            "month" : 2,
            "target" : 10000,
            "targetAchieved" : 101540.7
        },
        {
            "month" : 3,
            "target" : 15000,
            "targetAchieved" : 0
        },
        {
            "month" : 4,
            "target" : 15500,
            "targetAchieved" : 0
        },
        {
            "month" : 5,
            "target" : 15500,
            "targetAchieved" : 0
        },
        {
            "month" : 6,
            "target" : 16000,
            "targetAchieved" : 0
        },
        {
            "month" : 7,
            "target" : 16200,
            "targetAchieved" : 0
        },
        {
            "month" : 8,
            "target" : 17000,
            "targetAchieved" : 0
        },
        {
            "month" : 9,
            "target" : 18000,
            "targetAchieved" : 0
        },
        {
            "month" : 10,
            "target" : 19000,
            "targetAchieved" : 0
        },
        {
            "month" : 11,
            "target" : 20000,
            "targetAchieved" : 0
        },
        {
            "month" : 12,
            "target" : 19000,
            "targetAchieved" : 0
        }
    ],
    "franchiseeId" : "5c42bd6085edaa215cba5a21",
    "yearlyTarget" : {
        "year" : 2019,
        "target" : 197200,
        "targetAchieved" : 101540.7
    },
    "offer" : null,
    "status" : "1",
    "createdAt" : ISODate("2019-04-29T06:46:45.643-04:00"),
    "__v" : 0
}