DYNAMO DB* 查询仅插入和更新文档中的特定数组元素

问题描述 投票:0回答:2
需要 mongodb 查询:如果我在输入参数中得到

order

vendorID
 ,而该输入参数已经存在于特定的 
orderNumber
 中,我需要在 
orders
 数组中更新它,方法是将整个现有订单元素替换为 
orderNumber
 。输入参数中新提供的顺序,否则插入它

假设输入参数具有三个属性:

  1. orderNumber : "order2"
    
    
  2. order: {"orderNumber":"order2", "data":"NEW_DATA_FROM_INPUT" }
    
    
  3. vendorId : "vendor1"
    
    
这是数据库中的示例数据:

{ "_id":1, "vendorId":"Vendor1", "orders":[ { "orderNumber":"order1", "data":"data1" }, { "orderNumber":"order2", "data":"data2" } ] }
查询应更新记录如下:

{ "_id":1, "vendorId":"Vendor1", "orders":[ { "orderNumber":"order1", "data":"data1" }, { "orderNumber":"order2", "data":"NEW_DATA_FROM_INPUT" // !! } ] }
尝试过

$set

$addtoSet
,但由于 mongo 限制,它们不能在同一路径上一起使用。

node.js arrays mongodb mongoose nosql
2个回答
2
投票
一种方法是在更新中使用

聚合管道

注意:下面列出的

update

中的评论。根据您使用的应用程序/驱动程序,您可能需要将 
db.collection.update
 更改为其他内容(并且您可能不想要/不需要 
{"multi": true}
)。

db.collection.update({ // find doc with correct "vendorId" "vendorId": "Vendor1" }, // use pipeline [{ // rebuild "orders" "$set": { "orders": { "$let": { "vars": { // from input params "orderParam": { "orderNumber": "order2", "data": "NEW_DATA_FROM_INPUT" } }, "in": { "$cond": [ // does "orders.orderNumber" exist and is array? { "$eq": [{"$type": "$orders.orderNumber"}, "array"] }, // yes, "orders.orderNumber" exists and is array { "$cond": [ // does an order need rewriten "data"? { "$in": ["order2", "$orders.orderNumber"] }, // yes, rewrite specific order, keep the rest { "$map": { "input": "$orders", "as": "order", "in": { "$cond": [ // is this the order? { "$eq": ["$$order.orderNumber", "$$orderParam.orderNumber"] }, // yes, rewrite this order { "$mergeObjects": [ "$$order", {"data": "$$orderParam.data"} ] }, // not the order, so keep it "$$order" ] } } }, // no, order is not there, so just append it { "$concatArrays": ["$orders", ["$$orderParam"]] } ] }, // nobody home, create it ["$$orderParam"] ] } } } } } ], { "multi": true })

mongoplayground.net 上尝试一下,你会看到各种测试用例。


0
投票
在更新的情况下,我们可以将位置操作“

$”与updateOne()或updateMany()一起使用,这有助于更新要使用提供的值更新的第一个出现。

例如。在上述情况下,我们需要更新第二个索引对象值。

db.collection.updateOne({_id:1,"orders.orderNumber":"order2"},{$set:{ "orders.$.data": "NEW_DATA_FROM_INPUT" }});
    
© www.soinside.com 2019 - 2024. All rights reserved.