如果其他字段与MongoDB中的值匹配,如何更新数组中的字段

时间:2013-01-31 12:22:35

标签: mongodb updates

我在查询和更新MongoDb选择器的丛林中纠结了一点。

情况:我们有公司收藏。喜欢这样的

Companies.find({}) =>
 {_id: 1, item_amount: 5}, 
 {_id: 2, item_amount: 7}, 
 {_id: 3, item_amount: 10}

我们拥有一些具有某种结构的Users集合。用户想要购买任何物品,它可能会减少公司的价值并增加用户数量,只有一个条件 - 用户可能知道他在哪里购买物品。

{userId: _id,
 ownedItems: 
  [{company_id: 2, item_amount: 3},
  {company_id: 1, item_amount: 5}]
}

确定。我如何使用Users.update(),如果用户想要购买,例如,来自{_id: 3}的5个项目(我们不知道用户是否有company_id: 3的字段)

我认为这可能是这样的:

Companies.update({_id: 3}, {$inc: {item_amount: - 5}})
&安培;&安培;
Users.update({userId: _id}, {$set: {'ownedItems[x].company_id': 3}, $inc{'ownedItems[x].item_amount': 5})

但是因为有一些问题。
我怎么知道每个克林的[x]?解决?如果我需要添加新公司怎么办?
如果字段$set不存在,'ownedItems[x].company_id'会有效吗?

我可以在IF / Else声明中查看smth。例如,使用$exist$cond(用于聚合)选择器。但.find()总是返回一个游标(是吗?),而不是true或false。那可能会怎么做?我如何使用聚合选择器?像这样:

Users.find({_id: userId}, {$cond: [{$eq: ['owenedItem[x].company_id', _someId_]}, {$set:{...}}, {$push: {...}}]})

它会起作用吗?

1 个答案:

答案 0 :(得分:3)

听起来你想要将$ elemMatch运算符与'$'位置运算符结合使用:

http://docs.mongodb.org/manual/reference/operator/elemMatch/ http://docs.mongodb.org/manual/reference/operator/positional/

让我们举个例子吧。假设您要在用户的“ownedItems”列表中找到“company_id”为3的元素,并将该元素的“item_amount”更新为5.这可以在单个更新语句中完成,如下所示:

Users.update( { userId: _id, ownedItems : { $elemMatch : { company_id : 3 } } },
              { $inc : { ownedItems.$.item_amount : 5 } } )

$ elemMatch 运算符会明确显示您要查询的列表中的哪些元素。然后,您可以使用modifier子句中的 $ 运算符来引用该匹配的元素并对其进行更改。

如果用户的“ownedItems”列表没有匹配{“company_id”:3}的任何条目,则上述更新将不会执行任何操作。如果发生这种情况,您可以使用 $ addToSet 运算符进行第二次更新,以添加新条目,如下所示:

Users.update( { userId: _id },
              { $addToSet : { ownedItems : { company_id : 3, item_amount : 5 } } } )

http://docs.mongodb.org/manual/reference/operator/addToSet/