【问题标题】:parsing AggregationOutput mongo java driver解析AggregationOutput mongo java驱动
【发布时间】:2013-03-23 20:09:56
【问题描述】:

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

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

【问题讨论】:

    标签: java mongodb pojo aggregation-framework


    【解决方案1】:

    似乎您每次访问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);
    }
    

    【讨论】:

      【解决方案2】:

      我知道,这是一个旧线程,并且已经得到了回答,但答案是优化。 原因您得到重复答案的实际原因是,每次您请求 .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 循环使用起来要干净得多。这个答案只是为了澄清原因,而不是如何。

      【讨论】:

        【解决方案3】:

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

        例如:

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

        【讨论】:

          猜你喜欢
          • 2018-08-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-15
          • 2016-02-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多