计算mongodb中对象数组内的值

时间:2012-04-20 16:44:26

标签: mongodb mongodb-java

我正在尝试收集mongodb中的一组推文中的所有主题标签,并且我想计算每个主题标签在推文中出现的次数。 hcoll是使用此代码创建的主题标签的集合。

BasicDBObject key = new BasicDBObject("hashtag",hashtagobj.get("hashtag"));
BasicDBObject update = new BasicDBObject("$addtoSet", new BasicDBObject("tweetsid",hashtagobj.get("_id")));
update.put("$inc",new BasicDBObject("count", 1));
hcoll.update(key,update,true,false);    

但如果对于相同的推文再次执行此代码,那么即使第二次没有将tweetid添加到数组中,计数器“count”也会递增。

我正在寻找一种方法来增加“count”的值,只有当tweetid不在数组“tweetsid”中时。但我想用一个查询,因为我知道如何使用两个或更多的查询。如果这是不可能的,请告诉我,所以我只需要两个或更多的查询!谢谢:D

2 个答案:

答案 0 :(得分:3)

一种可能的解决方案是修改查询文档以声明所讨论的tweetid不在“tweetsid”数组中。如果是,则查询将不匹配,并且不会执行更新。

以下是使用JS shell的示例。没有示例文档很难给出确切的答案,所以我猜测了你的文档结构。希望它足够接近,所以这个例子与你相关。

> db.hcoll.save({_id:1, hashtag:"myHashTag", count:0, tweetsid:[]})
> db.hcoll.find()
{ "_id" : 1, "hashtag" : "myHashTag", "count" : 0, "tweetsid" : [ ] }

以下更新会将“id1”添加到“tweetsid”数组并增加“count by 1”的值

> db.hcoll.update({hashtag:"myHashTag", tweetsid:{$ne:"id1"}}, {$addToSet:{"tweetsid":"id1"}, $inc:{"count":1}})
> db.hcoll.find()
{ "_id" : 1, "count" : 1, "hashtag" : "myHashTag", "tweetsid" : [ "id1" ] }

如果再次执行更新,“count”将不会递增,因为查询的{tweetsid:{$ne:"id1"}}部分不匹配。

> db.hcoll.update({hashtag:"myHashTag", tweetsid:{$ne:"id1"}}, {$addToSet:{"tweetsid":"id1"}, $inc:{"count":1}})
> db.hcoll.update({hashtag:"myHashTag", tweetsid:{$ne:"id1"}}, {$addToSet:{"tweetsid":"id1"}, $inc:{"count":1}})
> db.hcoll.update({hashtag:"myHashTag", tweetsid:{$ne:"id1"}}, {$addToSet:{"tweetsid":"id1"}, $inc:{"count":1}})
> db.hcoll.find()
{ "_id" : 1, "count" : 1, "hashtag" : "myHashTag", "tweetsid" : [ "id1" ] }
>

我在帖子中看到您正在使用upsert = true执行更新,表示如果文档不存在,您希望创建该文档。不幸的是,我提出的更新不适用于upsert,因为如果新的“tweetsid”值在“tweetsid”数组中,则查询将不匹配,并且upsert将创建一个新文档。

> db.hcoll.update({hashtag:"myHashTag", tweetsid:{$ne:"id1"}}, {$addToSet:{"tweetsid":"id1"}, $inc:{"count":1}}, true, false)
> db.hcoll.find()
{ "_id" : 1, "count" : 1, "hashtag" : "myHashTag", "tweetsid" : [ "id1" ] }
{ "_id" : ObjectId("4f91ae48f48744310eab90d2"), "count" : 1, "hashtag" : "myHashTag", "tweetsid" : [ "id1" ] }
> 

希望以上内容能为您提供一些想法并帮助您找到解决方案。

答案 1 :(得分:1)

  

但我想用一个查询,因为我知道如何使用两个或更多查询来做到这一点。如果不可能,请告诉我......

这是不可能的。

事实上,我会更进一步,here is the JIRA ticket。你可以在JIRA那里投票。