Search code examples
javamongodbspring-data-mongodb

Is there any better way other than iterating through cursor of MongoDB?


I am doing the following business logic in my code

Cursor cursor = db.getCollection(CollectionInfo.ORDER).aggregate(pipelines, options);
        while (cursor.hasNext()) {
            orders.add(new Order(cursor.next().toMap()));
        }
        return orders;

So just to build the object I am iterating through all the documents. SO If I have a lot of documents as the result of aggregation. The iteration is taking a lot of time. Is there any better way to do this? With Spring data mongo DB or anything else?


Solution

  • Use mongoTemplate.aggregate(...).getMappedResults()

    @Autowired
    protected MongoTemplate mongoTemplate;
    ...
    
    List<AggregationOperation> pipeline = ...;
    Aggregation agg = Aggregation.newAggregation(pipeline)
        .withOptions(...);
    List<Orders> orders = mongoTemplate.aggregate(agg, CollectionInfo.ORDER, Order.class)
        .getMappedResults();
    

    Note: If your query returns more than 1K documents, it's recommended to use $skip / $limit

    Pseudocode

    skip  = 0
    limit = 1_000
    size  = 0
    do {
       
       //Add skip / limit (do not insert these stages more than once)
       pipeline.add(Aggregation.skip(skip))
       pipeline.add(Aggregation.limit(limit))
       
       //aggregate
       result = mongoTemplate.aggregate(...).getMappedResults();
       
       size  = result.size();
       skip += limit;
    // If there are 1_000 results, probably there are more items, keep iterating
    } while(size == limit);