首页 > 解决方案 > MongoDB - 如果 arrayFilters 不满足,则对数组执行 upsert

问题描述

我在 mongo 中存储了以下文档:

{
"_id" : ObjectId("5d1a08d2329a3c1374f176df"),
"associateID" : "1234567",
"associatePreferences" : [ 
    {
        "type" : "NOTIFICATION",
        "serviceCode" : "service-code",
        "eventCode" : "test-template",
        "preferences" : [ 
            "TEXT", 
            "EMAIL"
        ]
    }, 
    {
        "type" : "URGENT_NOTIFICATION",
        "serviceCode" : "service-code",
        "eventCode" : "test-template",
        "preferences" : [ 
            "TEXT"
        ]
    }
]
}

我基本上是在尝试根据它的类型、serviceCode 和 eventCode 查询 associatePreferences 数组的元素之一,并向首选项数组添加一个新值。但是,如果 type、serviceCode 和 eventCode 的组合不存在,我想用这些值向 associatePreferences 数组添加一个新元素。这是我当前的查询:

db.user_communication_preferences.update(
   {'associateID':'testassociate'}, 
   {$addToSet:{'associatePreferences.$[element].preferences':"NEW_VALUE"}}, 
   {arrayFilters:[{'element.serviceCode':'service-code-not-present', 'element.eventCode':'event-code-not-present','element.type':'URGENT_NOTIFICATION'}]}
)

如果所有 arrayFilters 都存在于 associatePreferences 的元素中,则此查询有效,但如果新元素不存在,则不会添加新元素。我错过了什么?

标签: mongodbmongodb-query

解决方案


您可以使用聚合管道检查元素的存在,然后有条件地将元素附加到associatePreferences数组中。最后,使用聚合结果更新您的文档。

db.user_communication_preferences.aggregate([
  {
    "$match": {
      "associateID": "testassociate"
    }
  },
  {
    "$addFields": {
      "filteredArray": {
        "$filter": {
          "input": "$associatePreferences",
          "as": "pref",
          "cond": {
            $and: [
              {
                $eq: [
                  "$$pref.type",
                  "URGENT_NOTIFICATION"
                ]
              },
              {
                $eq: [
                  "$$pref.eventCode",
                  "event-code-not-exists"
                ]
              },
              {
                $eq: [
                  "$$pref.serviceCode",
                  "service-code-not-exists"
                ]
              }
            ]
          }
        }
      }
    }
  },
  {
    $addFields: {
      "needAddElement": {
        $eq: [
          {
            "$size": "$filteredArray"
          },
          0
        ]
      }
    }
  },
  {
    "$addFields": {
      "associatePreferences": {
        "$concatArrays": [
          "$associatePreferences",
          {
            "$cond": {
              "if": {
                $eq: [
                  "$needAddElement",
                  true
                ]
              },
              "then": [
                {
                  "type": "URGENT_NOTIFICATION",
                  "serviceCode": "service-code-not-exists",
                  "eventCode": "event-code-not-exists",
                  "preferences": [
                    "TEXT"
                  ]
                }
              ],
              "else": []
            }
          }
        ]
      }
    }
  }
]).forEach(result){
    db.user_communication_preferences.update({
        _id : result._id
    }, {
        $set: {
            "associatePreferences" : result.associatePreferences
        }
    })
}

推荐阅读