Reputation: 275
I have the mongodb json data:
{
"_id" : ObjectId("1111111111111111"),
"teamId" : "111",
"scoreId" : "50dcefb52d764ca3913985a80a4162ef",
"utterances" : [
{
"text" : "test1",
"parsedText" : "test1"
},
{
"text" : "test2",
"parsedText" : "test2"
}
]
},
{
"_id" : ObjectId("22222222222222"),
"teamId" : "111",
"scoreId" : "60dcefb52d764ca3913985a80a4162ef",
"utterances" : [
{
"text" : "do it1",
"parsedText" : "do it1"
},
{
"text" : "do it2",
"parsedText" : "do it2"
},
{
"text" : "do it3",
"parsedText" : "do it3"
}
]
}
And mongo query is like:
db.teamScore.aggregate([
{$match : {teamId:"111"}},
{$unwind: '$utterances'},
{$group: {_id: '$_id', 'sum': { $sum: 1}}},
{$group: {_id: null, total_sum: {'$sum': '$sum'}}}
])
===>5
What I want to do is that total sum utterances using spring mongo aggregation
I am trying to make a source like:
Criteria creteria = Criteria.where("teamId").is("111");
MatchOperation matchStage = Aggregation.match(creteria);
GroupOperation group = group("scoreId")
.push("$utterances").as("utterances");
ProjectionOperation projectStage = project().and("scoreId").arrayElementAt(0).as("scoreId")
.and("utterances").size().as("count");
Aggregation aggregation = Aggregation.newAggregation(matchStage, unwind("utterances", true), group, projectStage);
AggregationResults<Intent> result = mongoTemplate.aggregate(aggregation, "intents", Intent.class);
List<Intent> results = result.getMappedResults();
How can I count utterances? I am new to mongodb so give me a tip to solve this problem. aggregation is best way to count array list,right?
Upvotes: 2
Views: 1403
Reputation: 75964
You can simplify your aggregation to below.
db.teamScore.aggregate([
{$match : {teamId:"111"}},
{$group: {_id: null, "total_sum": {"$sum": {"$size":"$utterances"}}}}
])
Spring code:
Criteria creteria = Criteria.where("teamId").is("111");
MatchOperation matchStage = Aggregation.match(creteria);
GroupOperation group = group()
.sum(ArrayOperators.Size.lengthOfArray("utterances")).as("count");
Aggregation aggregation = Aggregation.newAggregation(matchStage, group);
AggregationResults<Intent> result = mongoTemplate.aggregate(aggregation, "intents", Intent.class);
List<Intent> results = result.getMappedResults();
Upvotes: 2
Reputation: 27068
Here is one way to do it
Criteria criteria = Criteria.where("teamId").is("111");
MatchOperation matchOperation = match(criteria);
AggregationExpression aggregationExpression =
ArrayOperators.Size.lengthOfArray("utterances");
ProjectionOperation projectionOperation =
project("scoreId", "teamId").and(aggregationExpression).as("sum");
GroupOperation groupOperation = group("teamId").sum("sum").as("totalSum");
Aggregation aggregation = Aggregation.newAggregation(matchOperation, projectionOperation, groupOperation);
AggregationResults<BasicDBObject> team = mongoTemplate.aggregate(aggregation, "team", BasicDBObject.class);
Instead of BasicDBObject you can use your pojo and map the fields.
Upvotes: 0