【问题标题】:Filter array and $sum up field of filtered array mongodb过滤数组和过滤数组mongodb的$sum字段
【发布时间】:2018-08-19 04:41:06
【问题描述】:

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

我正在尝试总结 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
        ]
    ]
]);

但是 count 总是返回 0。我做错了什么?

【问题讨论】:

    标签: php mongodb mongodb-query aggregation-framework


    【解决方案1】:

    它总是返回 0,因为 $group 管道步骤中的 $sum 运算符需要一个计算为数值的表达式,但这里提供的 $map 表达式计算为一个数组。此外,$map 运算符的 in 值是应用于输入数组的每个元素的表达式,它使用as 中指定的变量名单独引用每个元素,因此没有过滤$cond 运算符在这里是多余的。

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

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

    $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
            ]
        ]
    ])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-23
      • 2016-03-18
      • 2022-11-19
      • 1970-01-01
      • 2019-11-23
      相关资源
      最近更新 更多