解析AggregationOutput mongo java驱动程序

时间:2013-03-23 20:09:57

标签: java mongodb pojo aggregation-framework

我有一个返回3个结果的聚合

{ "serverUsed" : "/127.0.0.1:27017" , "result" : [ { "_id" : "luke" , "times" : 56} , { "_id" : "albert" , "times" : 28} , { "_id" : "matt" , "times" : 28}] , "ok" : 1.0}
然而,当我尝试迭代结果时,代码进入无限循环(无法理解为什么!!)

AggregationOutput output = coll.aggregate( match1, unwind, match2, group, sort, limit);

Iterable<DBObject> list= output.results();
        while(list.iterator().hasNext()){

            String id = (String) list.iterator().next().get("_id");
            int times = Integer.parseInt(list.iterator().next().get("times").toString());

            System.out.println("ID IS "+id+" time: "+times);
        }

输出也重复了第一个结果:

ID IS luke time: 56
ID IS luke time: 56
ID IS luke time: 56
ID IS luke time: 56
ID IS luke time: 56
...

我真的不明白为什么这个迭代不起作用。请帮忙!

3 个答案:

答案 0 :(得分:6)

每次访问DBObject中的字段时,您似乎都在使用新的迭代器,即您在循环中多次使用list.iterator()list.iterator().next()返回集合中的第一个元素。因此,您最终会访问第一个DBObject

试试这个:

Iterable<DBObject> list= output.results();
while(list.iterator().hasNext()){
    DBObject obj = list.iterator().next();
    String id = obj.get("_id");
    int times = Integer.parseInt(obj.get("times").toString());

    System.out.println("ID IS "+id+" time: "+times);
}

或者也许使用foreach循环:

for (DBObject obj : output.results()) {
    String id = obj.get("_id");
    int times = Integer.parseInt(obj.get("times").toString());
    System.out.println("ID IS "+id+" time: "+times);
}

答案 1 :(得分:3)

我知道,这是一个旧线程,它已经得到了解答,但答案是优化。实际的原因为什么你得到重复的答案是每次你请求.iterator()时,它返回一个从列表顶部开始的迭代器对象。

所以while循环条件为:

list.iterator().hasNext()

将始终返回true。相应地,随后的

list.iterator().next()

将始终返回第一个元素。

应该做的是:

AggregationOutput output = coll.aggregate( match1, unwind, match2, group, sort, limit);
Iterable<DBObject> list= output.results();
Iterator<DBObject> iterator= list.iterator();

while(iterator.hasNext()){
    DBObject obj = iterator.next();

    String id = (String) obj.get("_id");
    int times = Integer.parseInt(obj.get("times").toString());

    System.out.println("ID IS "+id+" time: "+times);
}

但从技术上讲,@ Aqua提到的for循环使用起来要干净得多。这个答案只是为了澄清原因,而不是如何。

答案 2 :(得分:1)

您的代码中的一个可能缺陷是您多次调用Iterator.next()方法。将其值存储在变量中并使用变量而不是多次调用。

例如:

DBObject obj = list.iterator().next();
String id = (String) obj.get("_id"); 

int times = Integer.parseInt(obj.get("times").toString());`