我有一份看起来像这样的订单文件
{
"_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。因此,我需要能够查询子文档中的任何一个字段并更新数量。
请注意,我需要以原子方式完成更新。我真的不想一个接一个地做两个更新。
我在这里遗漏了什么吗?有另一种优雅的方式吗?
答案 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过滤。只有一个更新实际上会更改文档。