#aggregation-framework
#платформа агрегации
Вопрос:
Может ли кто-нибудь помочь мне с запросом для получения количества массивов bal по дате> 2015-08-02 и по дате <2016-05-02?
Моя коллекция:
{
"_id" : {
"a" : "NA",
"b" : "HXYZ",
"c" : "12345",
"d" : "AA"
},
"bal" : [
{
"type" : "E",
"date" : "2015-08-02"
},
{
"type" : "E",
"date" : "2017-08-01"
},
{
"type" : "E",
"date" : "2016-07-07"
}
]
}
Я попробовал следующий запрос,
db.getCollection(bal).aggregate([
{$match:{
"_id_a" : "NA"
}
},
{
$project: {
"bal": 1,
lessThanDate: {
$cond: [ {$lt:["$bal.date","2016-05-02"]}, 3, 0]
},
moreThanDate: {
$cond: [ {$gt:["$bal.date","2015-08-02"]}, 4, 0]
}
}
},
{
$group: {
_id: "$bal",
countSmaller: { $sum: "$lessThanDate" },
countBigger: { $sum: "$moreThanDate" }
}
}
])
Запрос выполняется не так, как ожидалось.
Ожидаемым результатом должно быть значение массива bal, равное 1.
Пожалуйста, помогите мне с запросом, поскольку я новичок в mongodb. Заранее спасибо.
Ответ №1:
$ facet может помочь здесь выбрать bal
значения на основе разных наборов условий
var maxDate = '2016-05-02';
var minDate = '2015-08-02';
db.getCollection('bal').aggregate([
{ $match: { '_id.a': 'NA' }},
{ $facet: {
'balancesBelowMax': [
{ $unwind: '$bal'},
{ $match: {'bal.date': {$lte: maxDate}}}
],
'balancesAboveMax': [
{ $unwind: '$bal'},
{ $match: {'bal.date': {$gte: minDate}}}
],
}},
{ $project: { balancesBelowMax: {$size: '$balancesBelowMax'}, balancesAboveMax: {$size: '$balancesBelowMax'} }}
])
Комментарии:
1. как мне получить сумму записей, большую, чем конкретная дата, и меньшую, чем конкретная дата
2. Отправленный мной запрос получит количество записей, как тех, что выше даты, так и тех, что ниже указанных дат. Что происходит, когда вы его запускаете?
Ответ №2:
Помимо пары изменений в вашем запросе, проблему можно решить с помощью $unwind во вложенном массиве.
db.getCollection("temp").aggregate([
{ "$unwind": "$bal"},
{$match:{
"_id.a" : "NA"
}
},
{
$project: {
"bal": 1,
lessThanDate: {
$cond: [ {$lt:["$bal.date",ISODate("2016-05-02")]}, 1, 0]
},
moreThanDate: {
$cond: [ {$gt:["$bal.date",ISODate("2015-08-02")]}, 1, 0]
}
}
},
{
$group: {
_id: "$bal.type",
countSmaller: { $sum: "$lessThanDate" },
countBigger: { $sum: "$moreThanDate" }
}
}
])
Я изменил следующие вещи:-
- Использование ISODate для дат вместо строки (вы можете использовать new Date(), если вам нужно использовать строку в качестве значения даты вместо ISODate())
- Изменение условия соответствия с «_id_a»: «NA» на «_id.a»: «NA»
- Группировка по bal.введите как _id (при необходимости вы можете указать другое поле)
- Использование $unwind
Вы можете прочитать больше о $ unwind здесь