过滤数组mongodb的过滤数组和$ sum up字段

时间:2018-03-10 20:14:27

标签: php mongodb mongodb-query aggregation-framework

对不起标题,我不知道如何更好地表达问题。

我试图将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
}

所以,我想总结所有卷对象的价格字段,但只有那些"买了"设置为true。结果我想得到这个输出:

{
  "_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
        ]
    ]
]);

但是计数总是会返回0.我做错了什么?

1 个答案:

答案 0 :(得分:1)

它始终返回0,因为 $sum 管道步骤中的 $group 运算符需要一个表达式,该表达式的计算结果为数值,提供的 $map 表达式计算结果。此外, $map 运算符的in值是一个表达式,应用于输入数组的每个元素,它们使用{{1}中指定的变量名称分别引用每个元素因此, $cond 运算符在这里是多余的,因此不涉及过滤。

您需要先使用 $filter 过滤数组,然后才能映射元素。幸运的是,对于您的情况,可以在 $sum 阶段使用 $project 运算符,因为它返回每个文档的指定表达式列表的总和

考虑运行以下管道以获得所需的结果:

as