【问题标题】:MongoDB aggregate query to SpringDataMongoDBMongoDB 对 SpringDataMongoDB 的聚合查询
【发布时间】:2017-12-05 11:50:54
【问题描述】:

我有以下 MongoDB 聚合查询,并希望它具有等效的 SpringData Mongodb 查询。

MongoDB 聚合查询:

db.response.aggregate(
        // Pipeline
        [
            // Stage 1 : Group by Emotion & Month
            {
                $group: {
                    _id: {
                        emotion: "$emotion",
                        category: "$category"
                    },
                    count: {
                        $sum: 1
                    },
                    point: {
                        $first: '$point'
                    }
                }
            },
            // Stage 2 : Total Points
            {
                $addFields: {
                    "totalPoint": {
                        $multiply: ["$point", "$count"]
                    }
                }
            },
                        // Stage3 : Group By Category - Overall Response Total & totalFeedbacks
            {
                $group: {
                    _id: '$_id.category',
                    totalFeedbacks: {
                        $sum: "$count"
                    },
                    overallResponseTotal: {
                        $sum: "$totalPoint"
                    }
                }
            },
                        // Stage4 - Overall Response Total & totalFeedbacks
            {
                $project: {
                    _id: 1,
                    overallResponseTotal: '$overallResponseTotal',
                    maxTotalFrom: {
                        "$multiply": ["$totalFeedbacks", 3.0]
                    },
                    percent: {
                        "$multiply": [{
                            "$divide": ["$overallResponseTotal", "$maxTotalFrom"]
                        }, 100.0]
                    }
                }
            },
                        // Stage4 - Percentage Monthwise
                {
                    $project: {
                        _id: 1,
                        overallResponseTotal: 1,
                        maxTotalFrom: 1,
                        percent: {
                            "$multiply": [{
                                "$divide": ["$overallResponseTotal", "$maxTotalFrom"]
                            }, 100.0]
                        }
                    }

                }
            ]
);

我已经在 Spring Data 中尝试过它的等价物,但在如何将“$addFields”转换为 java 代码的问题上停留在第 2 阶段。虽然我在多个网站上搜索它,但找不到任何有用的东西。请参阅我的阶段 1 等效 Java 代码。

//Stage 1 -Group By Emotion and Category and return it's count

GroupOperation groupEmotionAndCategory = Aggregation.group("emotion","category").count().as("count").first("point")
                        .as("point");

Aggregation aggregation = Aggregation.newAggregation(groupEmotionAndCategory);

AggregationResults<CategoryWiseEmotion> output = mongoTemplate.aggregate(aggregation, Response.class, CategoryWiseEmotion.class);

任何帮助将不胜感激。

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework spring-data-mongodb


    【解决方案1】:

    $addFields 还不是 Spring Data Mongodb 的 supported。

    一种解决方法是pass the raw aggregation pipeline to Spring。

    但由于第 1 阶段之后的字段数量有限,您也可以将第 2 阶段降级为projection:

    {
        $project: {
            // _id is included by default
            "count" : 1, // include count
            "point" : 1, // include point
            "totalPoint": {
                $multiply: ["$point", "$count"] // compute totalPoint
            }
        }
    }
    

    我自己没有测试过,但是这个预测应该转化为类似的东西:

    ProjectionOperation p = project("count", "point").and("point").multiply(Fields.field("count")).as("totalPoint");
    

    然后您可以类似地翻译阶段 3、4 和 5,并将整个管道传递给 Aggregation.aggregate()。

    【讨论】:

    • 感谢@Marc Tarin,它成功了!但现在我被困在第 4 阶段做乘法和除法。你能帮帮我吗?
    • 检查此thread 并尝试使用project(...).andExpression("overallResponseTotal / maxTotalFrom * 100.0").as("percent")。
    • Marc Tarin,对于 // Stage3:按类别分组 - 总体响应总数和总反馈。我用 Java GroupOperation groupCategoryOverAllResponseAndTotalFeedback = Aggregation.group("_id.category").sum("count") .as("totalFeedbacks").sum("totalPoint").as("overallResponseTotal"); 写了这个。但它给了我错误,因为无效参考 _id.category
    • 我不知道这背后的基本原理,但是 Spring 聚合框架不接受“_id”作为某些聚合阶段的有效字段名称。您必须稍作修改才能找到解决方法,也许是第 2 阶段的项目类别并在第 3 阶段引用它。请记住,您仍然可以将原始聚合传递给 Spring。它有助于加快开发速度,当您更熟悉 Spring 聚合框架的注意事项时,可以稍后再返回。
    猜你喜欢
    • 2019-06-18
    • 1970-01-01
    • 1970-01-01
    • 2021-09-27
    • 2020-07-27
    • 1970-01-01
    • 1970-01-01
    • 2020-03-09
    相关资源
    最近更新 更多