从MongoDB中的对象数组更新多个对象

hzbexzde  于 12个月前  发布在  Go
关注(0)|答案(1)|浏览(112)

我有一个类似于以下模式的MongoDB集合:

{
  "id": "1234657980", 
  "company": "samsung",
  "models": [
    {
      "name": "A1",
      "processor": "P1",
      "price": 10000
    },
    {
      "name": "A2",
      "processor": "P2",
      "price": 20000
    },
    {
      "name": "A3",
      "processor": "P3",
      "price": 30000
    }
  ]
}

我正在运行node js应用程序并使用mongoose。我想更新上面的集合,以使用以下数据更新模型数组:

{
  "name": "A1",
  "processor": "new P1",
  "price": 15000
}
{
  "name": "A2",
  "processor": "new P2",
  "price": 25000
}

基本上,这里我想替换A1和A2的数据,沿着,我想将新数据推入数组,如下所示

{
  "name": "A4",
  "processor": "P4",
  "price": 40000
}

我想更新A1和A2的值,同时在单个DB调用中将A4添加到同一个数组。我不想替换整个数组,因为真实的数据是安全敏感的,我不能替换整个对象,因为如果我为一个请求替换数据,同时另一个请求来更新数据,它将替换整个对象,我可能会丢失中间的数据,这将产生问题。这些数据非常敏感,我无法使用真实的属性名和结构,但我创建了集合的最小必需结构以用于调试目的。此外,在使用mongoose的bulkWrite()函数时也有一些限制。使用简单的if else条件将不起作用,因为它不是固定的,我总是会得到请求更新A1和A2的时间,但它将是一个单一的对象,甚至超过3-4个对象在同一时间沿着,有时它会有新的数据被推,有时没有。
我尝试在if else条件下使用多个$set,但我的数据是动态的,我无法控制更新时将获得多少个对象。我还尝试在一个updateMany()函数中使用$push和$set,但它不起作用。

cngwdvgl

cngwdvgl1#

如果你想维持秩序,
一个选项是使用更新管道,$reducingmodels数组,并检查与newArr比较的每个项目:

db.collection.update(
  {id: "1234657980"},
  [{$set: {models: {$let: {
          vars: {newArr: newArr},
          in: {$concatArrays: [
              {$reduce: {
                  input: "$models",
                  initialValue: [],
                  in: {$concatArrays: [
                      "$$value",
                      [
                        {$cond: [
                            {$in: ["$$this.name", "$$newArr.name"]},
                            {$first: {$filter: {
                                  input: "$$newArr",
                                  as: "newItem",
                                  cond: {$eq: ["$$this.name", "$$newItem.name"]}
                            }}},
                            "$$this"
                        ]}
                      ]
                  ]}
              }},
              {$filter: {
                  input: "$$newArr",
                  cond: {$not: {$in: ["$$this.name", "$models.name"]}}
              }}
          ]}
  }}}}]
)

了解它在playground example上的工作原理
否则,如果项目的顺序无关紧要,则有更简单的选项,例如newArrconcatArrays$filteredmodels

db.collection.update(
  {id: "1234657980"},
  [{$set: {models: {$let: {
          vars: {newArr: newArr},
          in: {$concatArrays: [
              {$filter: {
                  input: "$models",
                  cond: {$not: {$in: ["$$this.name", "$$newArr.name"]}}
              }},
              "$$newArr"
          ]}
  }}}}]
)

了解它在playground example上的工作原理

相关问题