通过spring-data迭代MongoDB中的大型集合

Rod*_*nko 22 java spring mongodb

朋友们!

我通过spring-data在java项目中使用MongoDB.我使用Repository接口来访问集合中的数据.对于某些处理,我需要迭代所有集合元素.我可以使用fetchAll方法的存储库,但它总是返回ArrayList.

然而,据推测,其中一个集合会很大 - 至少每个记录高达100万条记录.我想在这种情况下我不应该使用fetchAll,但我找不到方便的方法返回一些迭代器(可能允许部分获取集合),也没有方便的回调方法.

我见过只支持在页面中检索这样的集合.我想知道这是否是处理此类馆藏的唯一方式?

uda*_*mik 23

迟到的响应,但可能会帮助将来的某些人.)Spring数据不提供任何API来包装Mongo DB Cursor功能.它在find方法中使用它,但始终返回完整的对象列表.选项是直接使用Mongo API或使用Spring Data Paging API,如下所示:

        final int pageLimit = 300;
        int pageNumber = 0;
        Page<T> page = repository.findAll(new PageRequest(pageNumber, pageLimit));
        while (page.hasNextPage()) {
            processPageContent(page.getContent());
            page = repository.findAll(new PageRequest(++pageNumber, pageLimit));
        }
        // process last page
        processPageContent(page.getContent());
Run Code Online (Sandbox Code Playgroud)

  • 我只想稍后再说,对于大型数据集,你应该远离Paging API,因为它必须在构建每个页面之前遍历整个集合.这很快就会变得昂贵.坚持直接使用Mongo API. (11认同)
  • 出于对许多失去的时间的纯粹沮丧,希望节省别人的时间,我想重复肖恩布什所说的话。不要将它用于更大的收藏!您最终会得到使用限制和跳过的查询。每个跳过的文档都会被检查,这使得大页码的请求非常慢。 (4认同)

May*_*Mok 14

流作为游标:

@Query("{}")
Stream<Alarm>  findAllByCustomQueryAndStream();
Run Code Online (Sandbox Code Playgroud)

因此,对于大量数据,您可以流式传输它们并在没有内存限制的情况下逐行处理


Seg*_*ond 8

使用MongoTemplate :: stream()可能是DBCursor最合适的Java包装器


Jer*_*ook 7

您仍然可以使用mongoTemplate访问Collection并只使用DBCursor:

     DBCollection collection = mongoTemplate.getCollection("boundary");
     DBCursor cursor = collection.find();        
     while(cursor.hasNext()){
         DBObject obj = cursor.next();
         Object object =  obj.get("polygons");
         ..
      ...
     }
Run Code Online (Sandbox Code Playgroud)