2

我有一个返回 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
...

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

4

3 回答 3

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);
}
于 2013-03-23T20:22:06.083 回答
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 循环使用起来要干净得多。这个答案只是为了澄清原因,而不是如何。

于 2013-10-22T22:09:18.737 回答
1

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

例如:

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

int times = Integer.parseInt(obj.get("times").toString());`
于 2013-03-23T20:26:01.937 回答