Reputation: 31968
Given a Post
type document as:
@Getter
@AllArgsConstructor
class Post {
String publisher;
Set<String> interests;
}
From a collection of posts I am seeking to find out the Set<Result>
such that the Result
object would look like:
@Getter
@AllArgsConstructor
class Result {
String interestId;
String publisherId;
Long count;
}
To compare the operation with a java implementation, I am looking for something down the lines of the following method:
Set<Result> buildQuery(List<Post> postList) {
return postList.stream()
.flatMap(post -> post.getInterests().stream()
.map(interest -> new AbstractMap.SimpleEntry<>(interest, post.getPublisher())))
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet().stream()
.map(e -> new Result(e.getKey().getKey(), e.getKey().getValue(), e.getValue()))
.collect(Collectors.toSet());
}
While translating this to the mongodb query, this what I have until now:
db.posts.aggregate([
{"$unwind" :"$interestIds"},
{"$group" : {"_id": {interestId: "$interestIds", publisherId:"$publisherId"}, "count": {"$sum" : 1}}},
]);
This results in documents such as:
{
"_id" : {
"interestId" : "INTEREST1",
"publisherId" : "PUBLISHER2"
},
"count" : 3.0
}
Now, I am struggling to solve for the end map
operation to formulate this into an expected result which would be:
{
"_id" : ...
"interestId" : "INTEREST1",
"publisherId" : "PUBLISHER2"
"count" : 3.0
}
How can I fix my query to get the expected result?
Upvotes: 0
Views: 36
Reputation: 49975
$project is an equivalent of Java's map:
db.posts.aggregate([
{"$unwind" :"$interestIds"},
{"$group" : {"_id": {interestId: "$interestIds", publisherId:"$publisherId"}, "count": {"$sum" : 1}}},
{"$project":{ _id: 0, interestId: "$_id.interestId", publisherId: "$_id.publisherId", count: 1 }}
]);
Upvotes: 2