MongoDB - 更改密钥匹配的值

时间:2014-03-13 11:49:42

标签: mongodb mongodb-java

我有一个用户,在里面我保留了他评价的项目列表。

> db.users.findOne()
{
    "_id" : ObjectId("5321985944aebf2ca6f2075f"),
    "ratings" : [
        {
            "532192d344aebf2ca6f2075e" : 0
        },
        {
            "532199d144aebf2ca6f20760" : 1
        }
    ],
    "email" : "joe@example.com",
    "name" : "Joe Bloggs"
}

评级的格式如下:

{ item_id : <score> }

问题是,如果用户将同一项目评级两次(评级不同),而不是替换旧项目,则会将新元素添加到数组中。

我使用$addToSet来避免重复,但我想替换旧的评级。

我目前正以复杂的方式做这件事,有什么比这更简单了吗? (我使用的是Java,但如果解决方案没有,则无关紧要。)

2 个答案:

答案 0 :(得分:0)

你不应该使用$set吗?

db.users.update({"email":"joe@example.com"}, {$set:{"ratings.item_id":5}})

这样,如果没有早期评级,则会添加一个新评级。如果已经存在,则会更新。

注意:您需要更换&#34; item_id&#34;使用客户的实际商品ID。

答案 1 :(得分:0)

由于多种原因,这可能不是最好的架构设计。你会得到更好的服务:

{
    "_id" : ObjectId("5321985944aebf2ca6f2075f"),
    "ratings" : [
        {
            id: "532192d344aebf2ca6f2075e", score: 0
        },
        {
            id: "532199d144aebf2ca6f20760", score: 1
        }
    ],
    "email" : "joe@example.com",
    "name" : "Joe Bloggs"
}

至少以这种方式,您可以匹配数组元素的id

虽然你的问题。 $addToSet是一个很好的方便,但当然不能解决你的问题。它仍然可以使用,但是如果你想添加到&#34;得分&#34;像这样你必须使用(当然是新模型):

var count = db.collection.find({
  "_id" : ObjectId("5321985944aebf2ca6f2075f"),
  "ratings.id": "532192d344aebf2ca6f2075e" 
}).count();

if ( count != 0 ) {
   db.collection.update(
       {
           "_id" : ObjectId("5321985944aebf2ca6f2075f"),
           "ratings.id": "532192d344aebf2ca6f2075e" 
       },
       {
           "$inc": { "ratings.$.score": 1 }
       }
   );
} else {
    db.collection.update(
       {
           "_id" : ObjectId("5321985944aebf2ca6f2075f"),
           "ratings.id": "532192d344aebf2ca6f2075e" 
       },
       {
           "$push": {
               "id": newId,
               "score": newScore
           }
       }
    );
}

或者您的实施语言中的任何等效内容。

因此,$addToSet在您的情况下变得有点多余,因为您需要检查以确定您是$set还是$inc。更多参与,但它是唯一的方法。