Фильтрующий массив и поле $ sum для фильтруемого массива mongodb

Извините за название, я не знаю, как лучше выразить проблему.

Я пытаюсь суммировать общее количество потраченных денег на книги в документе MongoDB. Это означает, что перед вычислением массива необходимо отфильтровать, что при расчете общей суммы потраченных денег учитываются только купленные книги.

Это пример документа (я удалил некоторые поля, чтобы он не стал слишком большим):

{
"_id" : ObjectId("598cb3f4ca693a0688004e2a"),
"title" : {
"de" : "Another",
"ja" : "アナザー",
"roomaji" : "Another"},
"total" : 4,
"volumes" : [
{
"volume" : 1,
"edition" : 1,
"price" : 7,
"releaseDate" : 1342051200,
"bought" : true,
"read" : true
},
{
"volume" : 2,
"edition" : 1,
"price" : 7,
"releaseDate" : 1347494400,
"bought" : true,
"read" : true
},
{
"volume" : 3,
"edition" : 1,
"price" : 7,
"releaseDate" : 1352419200,
"bought" : false,
"read" : false
},
{
"volume" : 4,
"edition" : 1,
"price" : 7,
"releaseDate" : 1357776000,
"bought" : false,
"read" : false
}
],
"releaseYear" : 2012
}

Итак, я хочу суммировать ценовое поле для всех объектов объема, но только для тех, для которых «куплено» установлено в значение «истина». В результате я хотел бы получить этот вывод:

{
"_id" : ObjectId(),
"title" : {
'de' : 'title'
},
"count" : 14
}

И это мой PHP-код

$result = $mongo->Book->aggregate([
[
'$group' => [
'_id' => '$_id',
'title' => ['$push' => '$title.de'],
'count' => [
'$sum' => [
'$map' => [
'input' => '$volumes',
'as' => 'vol',
'in' => [
'$cond' => [
[
'$eq' => ['$$vol.bought', true]
],
'$$vol.price',
0
]
]
],
]
]
]
],
[
'$sort' => [
'count' => -1
]
]
]);

Но count всегда возвращает 0. Что я делаю не так?

1

Решение

Он всегда возвращает 0, потому что $sum оператор в $group шаг конвейера ожидает выражение, которое оценивается в числовое значение, но здесь предоставленный $map выражение оценивается в массив. Так же in значение $map оператор — это выражение, которое применяется к каждому элементу входного массива, который индивидуально ссылается на каждый элемент с именем переменной, заданным в as следовательно, в качестве $cond оператор здесь избыточен.

Вам нужно сначала отфильтровать массив, используя $filter тогда вы можете отобразить элементы. К счастью для вашего случая $sum Оператор может быть использован в $project stage, так как возвращает сумму указанного списка выражений для каждого документа.

Попробуйте получить следующий конвейер, чтобы получить желаемый результат:

$result = $mongo->Book->aggregate([
[
"$project" => [
"title.de" => "$title.de",
"count" => [
"$sum" => [
"$map" => [
"input" => [
"$filter" => [
"input" => "$volumes",
"as" => "vol",
"cond" => "$$vol.bought"]
],
"as" => "el",
"in" => "$$el.price"]
]
]
]
],
[
'$sort' => [
'count' => -1
]
]
])
1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector