2012-06-15 28 views
12

Bạn bè!Lặp lại bộ sưu tập lớn ở MongoDB qua số liệu mùa xuân

Tôi đang sử dụng MongoDB trong dự án java qua dữ liệu mùa xuân. Tôi sử dụng giao diện Repository để truy cập dữ liệu trong bộ sưu tập. Đối với một số xử lý, tôi cần phải lặp qua tất cả các phần tử của bộ sưu tập. Tôi có thể sử dụng phương thức fetchAll của kho lưu trữ, nhưng nó luôn trả về ArrayList.

Tuy nhiên, có nghĩa là một trong các bộ sưu tập sẽ lớn - tối đa 1 triệu bản ghi ít nhất một kilobyte mỗi bộ. Tôi cho rằng tôi không nên sử dụng fetchAll trong các trường hợp như vậy, nhưng tôi không thể tìm thấy các phương thức tiện lợi nào trả về một số iterator (có thể cho phép thu thập một phần), cũng như các phương thức thuận tiện với callbacks.

Tôi chỉ thấy hỗ trợ để truy xuất các bộ sưu tập đó trong các trang. Tôi tự hỏi liệu đó có phải là cách duy nhất để làm việc với những bộ sưu tập như vậy không?

+0

Bạn có thể sử dụng 'hạn()' chức năng để hạn chế các chức năng để lấy dữ liệu trong các khối –

+0

Tôi không quen thuộc với khung công tác mà bạn đang sử dụng, nhưng tôi sẽ thấy nó rất lạ nếu nó không có một số trình bao bọc cho các con trỏ của MongoDB. Bạn có chắc chắn rằng những gì bạn đang nhận được là một 'ArrayList', và không phải là một thực thi' List' tùy chỉnh mà quấn quanh một con trỏ? – thkala

+2

vâng, chắc chắn - Tôi vừa đăng nhập findAll(). GetClass() cho bộ sưu tập khoảng 3 triệu và tôi nghĩ rằng tôi đã thấy java.util.ArrayList ... –

Trả lời

17

Trả lời chậm, nhưng có thể sẽ giúp ai đó trong tương lai ..) Dữ liệu mùa xuân không cung cấp bất kỳ API nào để bọc Mongo DB Cursor khả năng. Nó sử dụng nó trong các phương thức find, nhưng luôn trả về danh sách các đối tượng đã hoàn thành. Tùy chọn là sử dụng Mongo API trực tiếp hoặc sử dụng mùa xuân dữ liệu Paging API, một cái gì đó như thế:

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

Tôi chỉ muốn kêu vang sau này và nói rằng bộ dữ liệu lớn, bạn cũng nên tránh xa API phân trang vì nó phải đi bộ toàn bộ bộ sưu tập trước khi tạo mỗi trang. Điều này nhanh chóng tốn kém. Gắn bó với việc sử dụng Mongo API trực tiếp. –

+0

@ShawnBush Bạn chắc chắn về điều này? – javadev

3

Một cách khác:

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

}while (!page.isLastPage()); 
7

Sử dụng MongoTemplate :: dòng() như lẽ là wrapper Java thích hợp nhất để DBCursor

6

bạn vẫn có thể sử dụng mongoTemplate để truy cập bộ sưu tập và chỉ cần sử dụng DBCursor:

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

Bạn có thể muốn thử cách DBCursor như sau:

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

Streams như con trỏ:

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

Vì vậy, đối với số lượng lớn các dữ liệu bạn có thể dòng họ và xử lý từng dòng nhưng không giới hạn bộ nhớ

Các vấn đề liên quan