Если вы просите вернуть группировку для "15" и "не 15" в результате, то вы ищете оператор $cond
, который позволит на основе "ветвления" по условной оценке.
Из содержимого оболочки вы можете использовать его следующим образом:
db.getCollection('student').aggregate([
{ "$group": {
"_id": null,
"countFiteen": {
"$sum": {
"$cond": [{ "$eq": [ "$student_age", 15 ] }, 1, 0 ]
}
},
"countNotFifteen": {
"$sum": {
"$cond": [{ "$ne": [ "$student_age", 15 ] }, 1, 0 ]
}
},
"sumNotFifteen": {
"$sum": {
"$cond": [{ "$ne": [ "$student_age", 15 ] }, "$student_age", 0 ]
}
}
}}
])
Таким образом, вы используете $cond
для выполнения логического теста, в этом случае, если "student_age"
в рассматриваемом текущем документе равно 15
или нет, то вы можете вернуть числовое значение в ответе 1
здесь для «подсчета» или фактического значения поля, когда это то, что вы хотите вместо этого отправить в аккумулятор. Короче говоря, это «троичный» оператор или условие if/then/else
(которое на самом деле может быть показано в более выразительной форме с ключами), которое можно использовать для проверки условия и определения того, что возвращать.
Для реализации Spring mongodb вы используете ConditionalOperators.Cond
для построения тех же выражений BSON:
import org.springframework.data.mongodb.core.aggregation.*;
ConditionalOperators.Cond isFifteen = ConditionalOperators.when(new Criteria("student_age").is(15))
.then(1).otherwise(0);
ConditionalOperators.Cond notFifteen = ConditionalOperators.when(new Criteria("student_age").ne(15))
.then(1).otherwise(0);
ConditionalOperators.Cond sumNotFifteen = ConditionalOperators.when(new Criteria("student_age").ne(15))
.thenValueOf("student_age").otherwise(0);
GroupOperation groupStage = Aggregation.group()
.sum(isFifteen).as("countFifteen")
.sum(notFifteen).as("countNotFifteen")
.sum(sumNotFifteen).as("sumNotFifteen");
Aggregation aggregation = Aggregation.newAggregation(groupStage);
Таким образом, вы просто расширяете эту логику, используя .then()
для «постоянного» значения, такого как 1
для «счетчиков» и .thenValueOf()
, где вам действительно нужно «значение» поля из документ, таким образом, в основном равный "$student_age"
, как показано для обозначения общей оболочки.
Поскольку ConditionalOperators.Cond
совместно использует интерфейс AggregationExpression
, это можно использовать с .sum()
в форме, которая принимает AggregationExpression
вместо строки. Это усовершенствование предыдущих выпусков spring mongo, которое потребовало бы от вас выполнения этапа $project
, чтобы существовали фактические свойства документа для вычисленного выражения до выполнения $group
.
Если все, что вам нужно, это скопировать исходный запрос для spring mongodb, то ваша ошибка заключалась в использовании этапа агрегации $count
вместо добавления к group()
:
Criteria where = Criteria.where("AGE").ne(15);
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(where),
Aggregation.group()
.sum("student_age").as("totalAge")
.count().as("countOfStudentNot15YearsOld")
);