使用mongodb shell,我能够执行一个检索整个文档的聚合查询。 为了做到这一点,我使用$$ ROOT变量。
db.reservations.aggregate([
{ $match : { hotelCode : "0360" } },
{ $sort : { confirmationNumber : -1 , timestamp: -1 } },
{ $group : {
_id : "$confirmationNumber",
timestamp :{$first : "$timestamp"},
fullDocument :{$first : "$$ROOT"}
}}
])
它检索内容为confirmationNumber,timestamp,fullDocument的对象。 fullDocument是整个文档。
我想知道是否可以对Spring-Data和聚合框架做同样的事情。
我的java代码是:
TypedAggregation<ReservationImage> aggregation = newAggregation(
ReservationImage.class,
match(where("hotelCode").is(hotelCode)),
sort(Direction.DESC,"confirmationNumber","timestamp"),
group("confirmationNumber").
first("timestamp").as("timestamp").
first("$$ROOT").as("reservationImage"));
List<myClass> items = mongoTemplate.aggregate(
aggregation,
myClass.class).getMappedResults();
错误是: org.springframework.data.mapping.PropertyReferenceException:找不到类型myClass的属性$$
你有什么想法吗?
感谢。
答案 0 :(得分:6)
我们创建了https://jira.spring.io/browse/DATAMONGO-954来跟踪从MongoDB管道表达式访问系统变量的支持。
一旦到位,您应该能够写下:
Aggregation agg = newAggregation( //
match(where("hotelCode").is("0360")), //
sort(Direction.DESC, "confirmationNumber", "timestamp"), //
group("confirmationNumber") //
.first("timestamp").as("timestamp") //
.first(Aggregation.ROOT).as("reservationImage") //
);
答案 1 :(得分:4)
我以前见过这种事情,它不仅限于$$ROOT
之类的变量名。 Spring数据有自己的想法,如何映射&#34;属性&#34;管道中的文件。另一个常见问题是简单地投射一个新的或计算的字段,该字段基本上具有新的&#34;属性&#34;它的名称无法识别。
最好的方法可能是“退出”&#34;从使用辅助类和方法并构造管道作为BSON文档。您甚至可以将底层集合对象和原始输出作为BSON文档获取,但最后仍然会转换为您键入的列表。
里程可能与您的实际方法不同,但基本上是:
DBObject match = new BasicDBObject(
"$match", new BasicDBObject(
"hotelCode", "0360"
)
);
DBObject sort = new BasicDBObject(
"$sort", new BasicDBObject(
"cofirmationNumber", -1
).append("timestamp", -1)
);
DBObject group = new BasicDBObject(
"$group", new BasicDBObject(
"_id", "confirmationNumber"
).append(
"timestamp", new BasicDBObject(
"$first", "$timestamp"
)
).append(
"reservationImage", new BasicDBObject(
"$first", "$$ROOT"
)
)
);
List<DBObject> pipeline = Arrays.asList(match,sort,group);
DBCollection collection = mongoOperation.getCollection("collection");
DBObject rawoutput = (DBObject)collection.aggregate(pipeline);
List<myClass> items = new AggregationResults(List<myClass>, rawoutput).getMappedResults();
主要的是远离正在阻碍并构建管道的帮助者,因为它应该没有强加的限制。