I have MongoDB Page and Post collections. Each page document has field postIds which is array of post Ids (String objects). I want to use aggregation to count number of posts (=number of elements in array postIds) for each page. I wrote Mongo Shell aggregation function which returns exactly what I want:
db.page.aggregate([
{$unwind : '$postIds'},
{$group : {_id: '$_id', 'sum': { $sum: 1}}}
])
and it returns this result:
{ "_id" : "3", "sum" : 3 }
{ "_id" : "2", "sum" : 3 }
This means that page with id 3 has 3 posts, and page with id 2 has 3 posts as well, which is correct.
Now I wanted to write same using Spring MongoDB Aggregation, and wrote this simple JUnit test:
/**
* Test page posts count
*/
@Test
public void testPagePostsCount() throws Exception{
MongoTemplate template = repository.getMongoTemplate();
Page page = new Page();
page.setPageId("2210");
page.setUserId("azec");
List<String> postList = new ArrayList<String>();
postList.add("53eb1a560efbe048c7ea698d");
postList.add("53eb1a6b0efbe048c7ea698e");
page.setPostIds(postList);
template.save(page);
Aggregation agg = newAggregation(
match(Criteria.where("pageId").is("2210")),
unwind("postIds"),
group("_id").sum("1").as("sum")
//project("$sum").and("pageId").previousOperation()
);
AggregationResults<PostCount> results = template.aggregate(agg, "page", PostCount.class);
List<PostCount> postCount = results.getMappedResults();
System.out.println("Done!");
}
However, this aggregation query returns this native Mongo query:
2014-08-13 20:06:07,949 DEBUG [org.springframework.data.mongodb.core.MongoTemplate] - Executing aggregation:
{
"aggregate":"page",
"pipeline":[
{
"$match":{
"pageId":"2210"
}
},
{
"$unwind":"$postIds"
},
{
"$group":{
"_id":"$_id",
"sum":{
"$sum":"$1"
}
}
}
]
}
Questions: 1. As you can see, the difference is with the $sum value of $1. I need to pass there number 1 instead of $1, but I am not sure how. 2. Do I need project operation here?
Thanks
I have figured this out finally. The key is to use count() aggregation function in Spring Data for MongoDB, which translates to sum increments by 1 in native Mongo shell. This is my final JUnit Test:
So finally this translates to following native aggregation operation: