2012-06-15 3 views
12

친구!스프링 데이터를 통해 MongoDB에서 대규모 콜렉션 반복

스프링 프로젝트를 통해 Java 프로젝트에서 MongoDB를 사용하고 있습니다. 저장소 인터페이스를 사용하여 컬렉션의 데이터에 액세스합니다. 일부 처리의 경우 컬렉션의 모든 요소를 ​​반복해야합니다. 나는 저장소의 fetchAll 메소드를 사용할 수 있지만 항상 ArrayList를 반환합니다.

그러나 컬렉션 중 하나가 커질 것으로 예상됩니다. 최대 100 만개의 레코드가 각각 수 킬로바이트입니다. 나는 그런 경우에 fetchAll을 사용하지 말아야한다고 생각하지만 일부 반복자 (부분적으로 콜렉션을 가져올 수 있도록 허용)를 반환하는 편리한 메소드 나 콜백을 사용하는 편리한 메소드를 찾지 못했습니다.

페이지에서 이러한 컬렉션을 검색하는 데 대한 지원 만 보았습니다. 그러한 컬렉션 작업을위한 유일한 방법인지 궁금합니다.

+0

당신은() '함수가 기능을 제한하는'제한을 사용할 수 있습니다 청크로 데이터를 검색하십시오. –

+0

사용중인 프레임 워크에 익숙하지 않지만 MongoDB의 커서에 대한 래퍼가없는 경우 매우 이상하게 보입니다. 당신이 얻는 것은'ArrayList'이고, 커서 주위를 감싸는 커스텀'List' 구현물이 아닙니까? – thkala

+2

네, 확실하게 - 저는 findAll(). getClass()를 약 3 백만개의 콜렉션에 대해 기록했습니다. 그리고 나는 java.util.ArrayList를 본 것으로 생각합니다 ... –

답변

17

늦은 응답이지만, 나중에 누군가에게 도움이 될 것입니다 ..) 봄 데이터는 모든 API를 제공하지 않습니다. Mongo DB 커서 기능. 그것은 find 메쏘드 내에서 그것을 사용하지만, 항상 객체의 완성 된 목록을 반환합니다. 문서 기준에 따라 결과를 처리하기 위해

do{ 
    page = repository.findAll(new PageRequest(pageNumber, pageLimit)); 
    pageNumber++; 

}while (!page.isLastPage()); 
+8

저는 나중에도 차임을하고 싶습니다. 많은 양의 데이터가 있다면 각 페이지를 작성하기 전에 전체 컬렉션을 거쳐야하므로 Paging API에서도 벗어나야합니다. 이것은 빨리 비싸게됩니다. Mongo API를 직접 사용하는 법을 고수하십시오. –

+0

@ShawnBush 확실한가요? – javadev

2

확인 새로운 방법 :

 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()); 
7

사용 MongoTemplate :: 스트림() 아마 가장 적절한 자바 래퍼 DBCursor하는

6
여전히 컬렉션에 액세스 할 수 mongoTemplate를 사용하여 간단하게 사용할 수 있습니다

DBCursor :

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

다음과 같이 DBCursor를 사용해보십시오.

DBObject query = new BasicDBObject(); //setup the query criteria 
    query.put("method", method); 
    query.put("ctime", (new BasicDBObject("$gte", bTime)).append("$lt", eTime)); 

    logger.debug("query: {}", query); 

    DBObject fields = new BasicDBObject(); //only get the needed fields. 
    fields.put("_id", 0); 
    fields.put("uId", 1); 
    fields.put("ctime", 1); 

    DBCursor dbCursor = mongoTemplate.getCollection("collectionName").find(query, fields); 

    while (dbCursor.hasNext()){ 
     DBObject object = dbCursor.next(); 
     logger.debug("object: {}", object); 
     //do something. 
    } 
1

스트림 커서 같은 : 많은 양의 데이터가 당신이 그들을 스트리밍 및 메모리 제한없이 라인으로 라인을 처리 할 수 ​​있습니다에 대한

@Query("{}") 
Stream<Alarm> findAllByCustomQueryAndStream(); 

그래서

관련 문제