MongoDB的Aggregation Sum在Spring Data上实现



HOUR_COUNTS集合包含{docId, hour, count}

对我来说,通过使用以下mongodb查询获得docId计数的总和是很容易的:

db.HOUR_COUNTS.aggregate(
    [
        {
            $match: { hour: { $gte: 10 } }
        },
        {
            $group: { _id: "$docId", total: { $sum: "$count" } }
        },
        { 
            $sort: { total: -1, _id: -1 }
        },
        {
            $limit: 20
        }
    ]
)

那么我可以得到以下结果:

{ "_id" : 6831, "total" : 6 }
{ "_id" : 6830, "total" : 6 }
{ "_id" : 6849, "total" : 4 }
{ "_id" : 6848, "total" : 4 }
{ "_id" : 6847, "total" : 3 }

是时候让我使用Spring Data

我试过这样做,但它不会工作:

    Aggregation agg = newAggregation(
            match(where("hour").gte(0)),
            project("docId"),
            group("docId").sum("count").as("total"), 
            project("total").and("docId").previousOperation(), 
            sort(Sort.Direction.DESC, "total", "docId"),
            limit(20)
        );

错误是:

java.lang.IllegalArgumentException: Invalid reference 'count'!

因此,我想知道如何使查询在Spring数据上工作。谢谢你。

为什么会这样呢?这才是你真正应该问自己的问题。

在聚合管道操作中,像 $project $group 这样的操作符只"返回"你显式要求它们返回的字段。作为"管道"概念,只有前一个管道阶段的"输出"可用于下一阶段及其后的阶段,除非可能再次修改。

因此,您在Java代码中编写的内容与您在shell中实验的内容不相等。您尝试引用先前$project操作排除的"字段"。所以不要这样做。你似乎对聚合管道中实际优化的情况有一个错误的看法:

    Aggregation agg = newAggregation(
        match(Criteria.where("hour").gte(10)),
        group("docId").sum("count").as("total"),
        sort(Sort.Direction.DESC, "total","docId"),
        limit(20)
    );

所以这实际上和你之前写的"一样"。您不需要额外的"项目"操作,它们对您的预期结果是有害的。

最新更新