如何在mongodb中使用Java聚合来多次查找字段的出现?

时间:2015-06-22 05:33:30

标签: java mongodb

我在mongodb中有一个集合 - " text_failed"其中包含我未能发送短信的所有号码,他们失败的时间以及其他一些信息。

此集合中的文档如下所示:

{
    _id(ObjectId): xxxxxx2af8....
    failTime(String): 2015-05-15 01:15:48
    telNum(String): 95634xxxxx
    //some other information    
}

我需要获取在一个月的时间内失败最多的前500名数字。在这个月中,一个数字可以出现任意数量的时间。(例如:一个数字失败了143次,其他46个等等)

我遇到的问题是在此期间数字失败超过7M。使用以下不使用聚合的代码处理这么多信息很困难:

    DBCollection collection = mongoDB.getCollection("text_failed");
    BasicDBObject query = new BasicDBObject();
    query.put("failTime", new BasicDBObject("$gt", "2015-05-15 00:00:00").append("$lt", "2015-06-15 00:00:00"));
    BasicDBObject field = new BasicDBObject();
    field.put("telNum", 1);

    DBCursor cursor = collection.find(query, field);
    HashMap<String, Integer> hm = new HashMap<String, Integer>();

    //int count = 1;
    System.out.println(cursor);
    while(cursor.hasNext()) {

        //System.out.println(count);
        //count++;
        DBObject object = cursor.next();

        if(hm.containsKey(object.get("telNum").toString())) {
            hm.put(object.get("telNum").toString(), hm.get(object.get("telNum").toString()) + 1);
        } 
        else {
            hm.put(object.get("telNum").toString(), 1);
        }

    }

这为我提取了7M +文档。我只需要前500名的数字。结果应如下所示:

{
    telNum: xxxxx54654 //the number which failed
    count: 129 //number of times it failed    
}

我自己使用聚合但没有得到预期的结果。这可以通过聚合来实现吗?或者还有其他更有效的方法可以做到这一点吗?

1 个答案:

答案 0 :(得分:0)

您可以尝试以下聚合管道:

db.getCollection("text_failed").aggregate([
    {
        "$match": {
            "failTime": { "$gt": "2015-05-01 00:00:00", "$lt": "2015-06-01 00:00:00" }
        }
    },
    {
        "$group": {
            "_id": "$telNum",
            "count": { "$sum": 1 }                
        }
    },
    {
        "$sort": { "count": -1 }
    },
    {
        "$limit": 500
    }
])