更新存在的数组或插入新的数组项

时间:2017-10-18 03:56:50

标签: mongodb mongodb-query

{
 _id:'1',
name:'apple',
option:[{
weight:'10',
price:'40',
},
{weight:'40',
price:'200'}]
}

我想添加苹果,如果它不在数据库中,如果它在数据库中,我想ckeck如果权重10可用,如果可用我想更新价格,如果不是我想在选项中添加新的重量和价格。我怎么能这样做,在mongodb。

1 个答案:

答案 0 :(得分:2)

您需要.bulkWrite()。这实际上不是单个操作,因此您希望在单个请求中提交多个操作。基本上尝试使用存储数据的$set$push不存在的新数据来编写更新:

db.collection.bulkWrite([
  { "updateOne": {
    "filter": { "_id": "1", "option.weight": "10" },
    "update": { 
      "$set": { "option.$.price": "30" }
    }
  }},
  { "updateOne": {
    "filter": { "_id": "1", "option.weight": { "$ne": "10" } },
    "update": {
      "$push": { "option": { "weight": "10", "price": "30" } }
    }
  }}
])

正面案例只是值,而$ne“否定”相等匹配,意味着该项目不存在。当然,positional $ operator$set一起使用

鉴于数据中只有一个操作实际匹配并作为更新应用,尽管在“批处理”中发送了两个操作。

如果你想要整个文档的“upserts”,那么你需要在其末尾添加另一个操作。请注意,您不能将“upsert”作为选项应用于其他任何一个语句,尤其是$ne,因为这会创建一个不存在数组项的新文档,而不仅仅是_id:< / p>

db.collection.bulkWrite([
  { "updateOne": {
    "filter": { "_id": "1", "option.weight": "10" },
    "update": { 
      "$set": { "option.$.price": "30" }
    }
  }},
  { "updateOne": {
    "filter": { "_id": "1", "option.weight": { "$ne": "10" } },
    "update": {
      "$push": { "option": { "weight": "10", "price": "30" } }
    }
  }},
  { "updateOne": {
    "filter": { "_id": 1 },
    "update": {
      "$setOnInsert": {
        "option": [
           { "weight": "10", "price": "30" }
         ]
      }
    },
    "upsert": true
  }}
])

$setOnInsert是主要的帮助,除了最后一个操作是唯一标记为"upsert"的操作。这种组合确保找到主要“文档”的位置,然后实际上没有发生任何事情,但是当找不到它时,会添加新的数组项。

作为旁注,我强烈建议将数值实际存储为数字而不是字符串。在大多数情况下,它不仅可以节省空间,而且在这方面也更有用。