mongoose 如何将多个arrayFilter组合为一个键

snz8szmq  于 11个月前  发布在  Go
关注(0)|答案(1)|浏览(102)

假设我有一个这样格式的schema:

const some_schema = new mongoose.Schema({
    "id": { type: Number },
    "list": [
        {
            id: { type: Number },
            value: { type: Number }
        }
    ]
})

字符串
我需要使用arrayFilters更新list中的多个对象,因为arrayFilters中的每个键都是唯一的,并且只能匹配list中的一个对象。
我可以使用JS来创建动态键,如下所示:

//original doc values:
{
    "id": 10,
    "list": [
        { id: 1, value: 5 },
        { id: 2, value: 10 }
     ]
}

let updates = [ { id: 1, newValue: 10 }, { id: 2, newValue: 20 }];
let queryOptions = { arrayFilters: [] }, queryUpdates = { $set: {} };

for (const key in updates) {
    queryOptions.arrayFilters.push({ [`${key}`]: key });
    queryUpdates.$set[[`elem.$[${key}].value`]] = updates[key].newValue;
}
//update query
await doc.updateOne(queryUpdates, queryOptions);

//updated doc values:
{
    "id": 10,
    "list": [
        { id: 1, value: 10 },
        { id: 2, value: 20 }
     ]
}


有没有什么方法可以直接在arrayFilters或者MongoDB中的其他方法中做到这一点,而不必像上面那样制作动态键?

6ovsh4lw

6ovsh4lw1#

您可以使用聚合管道处理更新。

  1. $let-使用updates数组对变量进行decompression。
    1.1. $map-迭代list数组中的每个元素。
    1.1.1. $mergeObjects-将当前迭代的元素(ori)与 1.1.1.1 的结果合并。如果结果存在,则当前迭代的元素的字段将被更新。否则,它将保持为原始元素。
    1.1.1.1. $first & $filter-通过匹配idnewList中获取第一个匹配元素。
await doc.updateOne({
  id: 10 // Update condition
},
[
  {
    $set: {
      list: {
        $let: {
          vars: {
            newList: updates
          },
          in: {
            $map: {
              input: "$list",
              as: "ori",
              in: {
                $mergeObjects: [
                  "$$ori",
                  {
                    $first: {
                      $filter: {
                        input: "$$newList",
                        cond: {
                          $eq: [
                            "$$this.id",
                            "$$ori.id"
                          ]
                        }
                      }
                    }
                  }
                ]
              }
            }
          }
        }
      }
    }
  }
])

字符串
请注意,updates数组中的对象必须具有与文档中相同的字段名称,以便更新(覆盖)值。
Demo @ Mongo Playground

相关问题