Spring MongoTemplate - Mapping aggregation result to collections (e.g. List and Map)

Harish picture Harish · Jul 6, 2017 · Viewed 7.2k times · Source

aggregate method of MongoTemplate returns AggregationResults<T>, where T being the class that corresponds to mongo collection.

Sometimes, we only want the single (say property abc) or a couple of properties (pqr and xyz) from that collection depending on particular criteria. In these cases, we can either retrieve the whole collection into T class or create a new class that contains properties (abc) or (pqr, xyz).

Is there a way to map these single property to List<String> or two properties as a key-value pair in HashMap<String, String>?

Answer

s7vr picture s7vr · Jul 6, 2017

Use BasicDBObject (backed by LinkedHashMap) / Document (from 2.0.0 spring mongo version) along with java 8 stream methods to parse them into collection types.

Single Property (abc) - List type

Aggregation aggregation = Aggregation.newAggregation(Aggregation.project("abc"));
List<String> singleResults = mongoOperations.aggregate(aggregation, "collectioname", BasicDBObject.class).getMappedResults().stream().map(item -> item.getString("abc")).collect(Collectors.toList());

Multiple properties (pqr, xyz) - Map type

Aggregation aggregation = Aggregation.newAggregation(Aggregation.project("pqr, xyz"));
List<Map> multipleResults = mongoOperations.aggregate(aggregation,"collectioname", BasicDBObject.class).getMappedResults().stream().map (item -> (LinkedHashMap) item).collect(Collectors.toList());

Update ( Reading from server )

Single Property (abc) - List type

Aggregation aggregation = Aggregation.newAggregation(Aggregation.group().push("abc").as("abc"));
List<String> singleResults = (List<String>) mongoOperations.aggregate(aggregation, "collectioname", BasicDBObject.class).getUniqueMappedResult().get("abc");

Multiple properties (pqr, xyz) - Map type

Aggregation aggregation = Aggregation.newAggregation(Aggregation.group().push("pqr").as("pqr").push("xyz").as("xyz"));
Map multipleResults = mongoOperations.aggregate(aggregation,"collectioname", BasicDBObject.class).getUniqueMappedResult();