Che*_*man 0 java mongodb spring-data aggregation-framework
使用mongodb shell,我能够执行一个检索整个文档的聚合查询.为了做到这一点,我使用$$ ROOT变量.
db.reservations.aggregate([
{ $match : { hotelCode : "0360" } },
{ $sort : { confirmationNumber : -1 , timestamp: -1 } },
{ $group : {
_id : "$confirmationNumber",
timestamp :{$first : "$timestamp"},
fullDocument :{$first : "$$ROOT"}
}}
])
Run Code Online (Sandbox Code Playgroud)
它检索内容为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();
Run Code Online (Sandbox Code Playgroud)
错误是:org.springframework.data.mapping.PropertyReferenceException:找不到类型myClass的属性$$
你有什么想法?
谢谢.
我们创建了https://jira.spring.io/browse/DATAMONGO-954来跟踪从MongoDB Pipeline表达式访问系统变量的支持.
一旦到位,您应该能够写:
Aggregation agg = newAggregation( //
match(where("hotelCode").is("0360")), //
sort(Direction.DESC, "confirmationNumber", "timestamp"), //
group("confirmationNumber") //
.first("timestamp").as("timestamp") //
.first(Aggregation.ROOT).as("reservationImage") //
);
Run Code Online (Sandbox Code Playgroud)
我以前见过这种事情,它不仅仅限于变量名称,例如$$ROOT. Spring data 对于如何在管道中映射文档的“属性”有自己的想法。另一个常见问题是简单地投影一个新的或计算的字段,该字段本质上具有一个无法识别的新“属性”名称。
也许最好的方法是“放弃”使用辅助类和方法,并将管道构建为 BSON 文档。您甚至可以获取底层集合对象和原始输出作为 BSON 文档,但最后仍然转换为您类型化的 List。
里程可能会因您的实际方法而异,但本质上是:
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();
Run Code Online (Sandbox Code Playgroud)
最重要的是远离那些阻碍的帮助者并建造管道,因为它应该不受强加的限制。
| 归档时间: |
|
| 查看次数: |
2764 次 |
| 最近记录: |