Вы должны были бы использовать структуру агрегации, где вы бы запустить трубопровод агрегации, который имеет оператор стадию конвейера $group
который агрегирует документы для создания желаемых отсчетов с помощью оператора аккумуляторного $sum
.
Для желаемого результата, вам нужно будет использовать tenary оператор как $cond
создать независимые поля подсчета, так что будет кормить количество документов для выражения в $sum
в зависимости от значения имени. Оператор $cond
может быть эффективно использован для оценки значений на основе значения поля reply
. Он принимает логическое условие в качестве своего первого аргумента (если), а затем возвращает второй аргумент, где оценка истинна (тогда) или третий аргумент, где false (else). Это преобразует true/false
булевых оцениваемые возвращается в 1 и 0, которые будут использованы в $sum
соответственно:
"$cond": [
{ "$eq": ["$reply", ">"] },
1, 0
]
Таким образом, если в документе, который обрабатывается "$reply"
поля имеет значение ">"
, оператор $cond
подают значение 1 до $sum
иначе оно суммирует нулевое значение.
Используйте $project
, как ваш последний шаг трубопровода, поскольку это позволяет изменить форму каждого документа в потоке, включают в себя, исключить или переименовать поля, впрыснуть вычисляемых полей, создания полей поддокументу, используя математические выражения, даты, строки и/или логические (сравнение, логические, управляющие) выражения. Он похож на SELECT
в SQL.
Следующий трубопровод должен вернуться к желаемому результату:
Model.aggregate([
{
"$group": {
"_id": "$criterion",
">": {
"$sum": {
"$cond": [
{ "$eq": [ "$reply", ">" ] },
1, 0
]
}
},
"<": {
"$sum": {
"$cond": [
{ "$eq": [ "$reply", "<" ] },
1, 0
]
}
}
}
},
{
"$project": {
"_id": 0,
"criterion": "$_id",
"result.>": "$>",
"result.<": "$<"
}
}
]).exec(function(err, result) {
console.log(JSON.stringify(result, null, 4));
});
Console Примера вывод
{
"criterion" : "story",
"result" : {
">" : 1,
"<" : 2
}
}
Примечания: Этот подход учитывает значения для $reply
полей являются фиксированными и поэтому он не является гибким, когда значения являются динамическими и неизвестными.
Для более гибкой альтернативы, которая выполняет гораздо быстрее, чем выше, имеет более высокую производительность, а также учитывает неизвестные значения для количества полей, я бы предложил запустить трубопровод следующим образом:
Model.aggregate([
{
"$group": {
"_id": {
"criterion": "$criterion",
"reply": "$reply"
},
"count": { "$sum": 1 }
}
},
{
"$group": {
"_id": "$_id.criterion",
"result": {
"$push": {
"reply": "$_id.reply",
"count": "$count"
}
}
}
}
]).exec(function(err, result) {
console.log(JSON.stringify(result, null, 4));
});
Пример консоли Выход
{
"_id" : "story",
"result" : [
{
"reply" : "<",
"count" : 2
},
{
"reply" : ">",
"count" : 1
}
]
}
действительно блестящая работа там огромное спасибо @chridam Это было очень полезно. Вы поняли мою проблему. – neaGaze
@neaGaze Не беспокойтесь, всегда рад помочь :) – chridam