【问题标题】:MongoDB update inside 2 nested arrays of objectsMongoDB 在 2 个嵌套的对象数组内更新
【发布时间】:2014-03-23 15:53:58
【问题描述】:

我目前正在开发一个我们正在使用 mongodb 的应用程序,我是新手,在复杂的更新方面遇到了很多挑战

这是我们的收货单:

{
   "_id" : ObjectId(),
   "company" : String,
   "employee" : String,
   "office" : String,
   "status" : String,
   "subOrders" : [ 
    {
        "products" : [ 
            {
                "productId" : ObjectId(),
                "name" : String,
                "price" : String,
                "status" : String
            }
        ],
        "tax" : Int,
        "subTotal" : Int,
        "total" : "Int,
        "status" : String,
        "orderNote" : String
    }
  ]
}

我们需要提交如下更新

   update the subOrders.products.status to something ( for example : delivered )

在哪里

company = "x company" and office = "y office" and subOrders.products.productId = "z id" 

谁能给我们一个干净的代码来处理这个查询

请不要提供指向博客或网站的链接,除非它们针对的是非常相似的问题

提前致谢

【问题讨论】:

    标签: mongodb updates database


    【解决方案1】:

    你可以尝试这样的事情(这会很棒,但是......看看问题更新部分):

    db.coll.update(
        { company: "x company", office: "y office", "subOrders.products.productId": "z id"},
        { $set: { "subOrders.$.products.$.status": "delivered" } }
    )
    

    您还可以阅读有关更新操作的文档:http://docs.mongodb.org/manual/reference/method/db.collection.update/

    更新:
    操作.. 抱歉,位置运算符 ($) 不适用于嵌套数组...您可以在 JIRAdocumentation 上看到它。
    一些相关问题:12
    如果可能的话,您可以使用"subOrders.$.products.0.status" 而不是"subOrders.$.products.$.status"。但是,如果您向架构添加一些更改并摆脱更新嵌套数组中的文档的需要,那会更好。
    但总的来说,更新语法看起来像前面所示。

    更新 2:
    对于仅在一个子订单中仅查找一个文档并更新 status 的一个产品,您可以执行以下操作:

    var productIdForUpdate = "z id";
    var doc = db.coll.findOne({ company: "x company", office: "y office", "subOrders.products.productId": productIdForUpdate });
    top:
    for(var i = 0; i < doc.subOrders.length; i++) {
        var subOrder = doc.subOrders[i];
        for(var j = 0; j < subOrder.products.length; j++) {
            var product = subOrder.products[j];
            if (product.productId == productIdForUpdate) {
                eval('db.coll.update({ _id: doc._id }, { $set: { "subOrders.' + i + '.products.' + j + '.status": "delivered" } } )');
                break top;   
            }
        }    
    }
    

    或:

    var productIdForUpdate = "z id";
    var doc = db.coll.findOne({ company: "x company", office: "y office", "subOrders.products.productId": productIdForUpdate });
    top:
    for(var i = 0; i < doc.subOrders.length; i++) {
        var subOrder = doc.subOrders[i];
        for(var j = 0; j < subOrder.products.length; j++) {
            var product = subOrder.products[j];
            if (product.productId == productIdForUpdate) {
                product.status = "delivered";
                db.coll.save(doc);
                break top;   
            }
        }    
    }
    

    显示的代码仅在一个子订单中更新具有特定索引的一种产品。如果您要更新多个文档或多个 subOrder... 或多个产品,则应在此代码中添加一些更改。

    【讨论】:

    • 感谢您编辑我也注意到的答案,我意识到嵌套数组的 $ 运算符不起作用,如果我们有需要更新的确切产品的索引,则可以使用第二个选项,所以让我们将问题改为:如果我们具备上述所有条件,我的意思是:{ company: "x company", office: "y office", "subOrders.products.productId": "z id" } 是否有可能获得匹配条件的 subOrders.products 数组的索引,然后在索引更新的帮助下
    • 感谢您的回答,尽管需要进行一些修改才能使其正常工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多