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)
);
所以这实际上和你之前写的"一样"。您不需要额外的"项目"操作,它们对您的预期结果是有害的。