更新在mongodb中使用$或condition查询的子文档

时间:2012-03-29 17:44:03

标签: mongodb

我有一份看起来像这样的订单文件

{ 
    "_id" : ObjectId("4f70ba6dfb59c87f6b07a1ad"), 
    "state" : "CART", "storeId" : "1", "userId" : "johndoe", 
    "orderItems" : [
        {
            "productId" : "169",
            "offerId" : "112233",
            "sku" : "product-sku-1",
            "name" : "Product Awesome A",
            "quantity" : 1,
            "retailPrice" : 495,
            "salePrice" : 395
        },
        {
            "productId" : "170",
            "offerId" : "112234",
            "sku" : "product-sku-2",
            "name" : "Product Awesome B",
            "quantity" : 1,
            "retailPrice" : 595,
            "salePrice" : 495
        }
    ]
}

问题:我想找到一个orderItem,它具有productId或sku,其值为product-sku-1,并将数量设置为2.

所以,我尝试了以下

db.order.update(
    { 
      "userId":"johndoe", "state":"CART",
      $or: [ 
             {"orderItems.productId":"product-sku-1"}, 
             {"orderItems.sku":"product-sku-1"}
      ]
    },
    { 
      $set : {"orderItems.$.quantity":2}
    }
)

这给了我一个错误

"can't append to array using string field name [$]"

如果我删除或条件并仅查询子文档的一个字段,如下所示,一切正常,数量设置为2。

db.order.update(
    { 
      "userId":"johndoe", "state":"CART",
      "orderItems.sku":"product-sku-1"
    },
    { 
      $set : {"orderItems.$.quantity":2}
    }
)

我的应用程序接收sku或productId作为标识符字段。我不知道在查询时它是sku还是productId。因此,我需要能够查询子文档中的任何一个字段并更新数量。

请注意,我需要以原子方式完成更新。我真的不想一个接一个地做两个更新。

我在这里遗漏了什么吗?有另一种优雅的方式吗?

2 个答案:

答案 0 :(得分:4)

我仔细阅读了点符号和sub-objects in this post之间的区别后找到了答案。我找到了以下解决方案:

db.order.update(
    { 
      "userId":"johndoe", "state":"CART",
      "orderItems" : { 
          $elemMatch : { $or:[{"productId":"product-sku-1"}, {"sku":"product-sku-1"}] }
      }
    },
    { 
      $set : {"orderItems.$.quantity":2}
    }
)

答案 1 :(得分:0)

不支持使用$。 $或查询没有设置$ position运算符的值,所以MongoDB认为你正在寻找一个名为“$”的字段,这是禁止的。

我建议您只发出两个更新,一个按productId过滤,另一个按sku过滤。只有一个更新实际上会更改文档。