Spring MongoDB数据聚合中的错误引用

Spring MongoDB数据聚合中的错误引用,mongodb,grouping,aggregation-framework,spring-data-mongodb,subdocument,Mongodb,Grouping,Aggregation Framework,Spring Data Mongodb,Subdocument,我有以下类型的mongodb文档: { "_id" : { "refId" : ObjectId("55e44dd70a975a6fec7ae66e"), "someString" : "foo" }, "someValue" : 1, "date" : NumberLong("1441025536869"), "subdoc" : { "someRef" : ObjectId("xf2h55e44dd70a975a6fec7a"), "count" : 99 }

我有以下类型的mongodb文档:

{
"_id" : {
    "refId" : ObjectId("55e44dd70a975a6fec7ae66e"),
    "someString" : "foo"
},
"someValue" : 1,
"date" : NumberLong("1441025536869"),
"subdoc" : {
    "someRef" : ObjectId("xf2h55e44dd70a975a6fec7a"),
    "count" : 99
}
}
要获取具有唯一的
“subdoc.someRef”
和最早的
“日期”
(如果有任何文档具有相同的
“subdoc.someRef”
)并按任何字段排序的文档列表。问题按字段
“subdoc.count”
排序。 我使用以下spring数据聚合:

Aggregation agg = Aggregation.newAggregation(
            Aggregation.match(match),
            Aggregation.project("date", "someValue")
                    .and("subdoc.someRef").as("someRef")
                    .and("subdoc.count").as("count")
                    .and("_id.someString").as("someString")
                    .and("_id.refId").as("refId"),
            Aggregation.sort(Sort.Direction.ASC, "date"),
            Aggregation.group("someRef")
                    .min("date").as("date")
                    .first("refId").as("refId")
                    .first("someValue").as("someValue")
                    .first("count").as("count"),
            Aggregation.project("someValue", "date", "refId", "count")
                    .and("_id").as("someRef"),
            Aggregation.sort(pageable.getSort()),
            Aggregation.skip(pageable.getOffset()),
            Aggregation.limit(pageable.getPageSize())
    );
除了spring数据如何转换外,一切都很好:.first(“count”).as(“count”) 我总是在聚合结果中得到
“count”
:null。 spring创建的DBObject不是我所期望的。日志中的这一行与我有关:

"$group" : { "_id" : "$someRef" , "date" : { "$min" : "$date"} , "refId" : { "$first" : "$_id.refId"} , "someValue" : { "$first" : "$someValue"} , "count" : { "$first" : "$subdoc.count"}}}
我不明白为什么它总是放
“$subdoc.count”
,而不是放
“$count”
,这是聚合管道上一步的结果。所以结果中的“count”总是空的,因为在最后一个grop步骤中,
“$subdoc.count”
总是空的。
如何让Spring使用我想要的值而不是引用?

多亏了评论,解决方案是消除预测和更新group stage。分组可以很好地处理子文档引用,这是我没有想到的:

    Aggregation agg = Aggregation.newAggregation(
            Aggregation.match(match),
            Aggregation.sort(Sort.Direction.ASC, "date"),
            Aggregation.group("subdoc.someRef")
                    .first("subdoc.count").as("count")
                    .first("_id.refId").as("refId")
                    .first("_id.someString").as("someString")
                    .first("date").as("date")
                    .first("someValue").as("someValue"),
            Aggregation.sort(pageable.getSort()),
            Aggregation.skip(pageable.getOffset()),
            Aggregation.limit(pageable.getPageSize())
    );

在这里,最让你头疼的是
$project
阶段,而这两个阶段都不是你真正需要的。每个聚合管道阶段实际上都必须通过该阶段可用的所有数据,这意味着它会占用时间和资源。因此,您的管道应该是
[匹配、排序、分组、排序、跳过、限制]
,而不需要对键进行任何重命名。只要在
中需要的地方引用
“subdoc.field”
,当然,对于“非点”名称使用
.as()
(因为
$group
中不允许这样做)。最好快点。另外,排序后,当其他字段都是
$first
时,
$min
中没有太多意义。感谢@BlakesSeven,我错过了在
first()
运算符中使用虚线名称的可能性。这一点确实是不应该的。不需要这样做,因此“正确”的方法是完全删除
$project
阶段。这里的问题是
springmongo
会“记住”原始文档结构,因此会引用原来的文档结构。但是没有附加的阶段更有效,因此不应该在这里应用。