Ik heb dit eindelijk bedacht. De sleutel is om de aggregatiefunctie count() te gebruiken in Spring Data voor MongoDB, wat zich vertaalt in somverhogingen met 1 in de native Mongo-shell. Dit is mijn laatste 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("_id").is("2210")),
unwind("postIds"),
group("_id").count().as("nPosts"),
project("nPosts").and("_id").as("pageId")
);
AggregationResults<PostCount> results = template.aggregate(agg, "page", PostCount.class);
List<PostCount> postCount = results.getMappedResults();
Assert.assertTrue(!postCount.isEmpty());
Assert.assertTrue(postCount.get(0).nPosts == 2);
Assert.assertTrue(postCount.get(0).pageId.equals("2210"));
}
private class PostCount {
String pageId;
int nPosts;
}
Dus uiteindelijk vertaalt dit zich naar de volgende native aggregatiebewerking:
{
"aggregate":"page",
"pipeline":[
{
"$match":{
"_id":"2210"
}
},
{
"$unwind":"$postIds"
},
{
"$group":{
"_id":"$_id",
"nPosts":{
"$sum":1
}
}
},
{
"$project":{
"nPosts":1,
"pageId":"$_id"
}
}
]
}