【问题标题】:using $$ROOT inside Spring Data Mongodb for retrieving whole document在 Spring Data Mongodb 中使用 $$ROOT 来检索整个文档
【发布时间】:2014-08-02 20:55:42
【问题描述】:

使用 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 的属性 $$

你有什么想法吗?

谢谢。

【问题讨论】:

  • 为什么不应该一样呢?您发现任何不同之处的实际 Java 代码是什么?
  • 感谢您的回复。我将在我的问题中添加我的 java 代码

标签: java mongodb spring-data aggregation-framework


【解决方案1】:

我以前见过这种东西,它不仅限于变量名,例如$$ROOT。 Spring data 对如何在管道中映射文档的“属性”有自己的想法。另一个常见问题是简单地投影一个新的或计算的字段,该字段本质上具有一个无法识别的新“属性”名称。

可能最好的方法是“退出”使用辅助类和方法,并将管道构建为 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();

主要的事情是远离阻碍并建造管道的帮手,因为它应该不受强加的限制。

【讨论】:

  • 感谢你们的cmets。 “另一个常见问题是简单地投影一个新的或计算的字段,该字段本质上具有一个无法识别的新“属性”名称。”你手头有一个例子来说明你想用 Spring Data MongoDB 做什么?
  • @ThomasDarimont 我遇到了一些。我现在的就寝时间。如果有提交 JIRA 问题或任何错误跟踪的地方,请告诉我。如果需要,我会挖掘一个案例并针对行李箱进行测试。
  • 你可以在这里找到 Spring Data MongoDB 的 JIRA:jira.spring.io/browse/DATAMONGO
【解决方案2】:

我们创建了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") //
);

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-18
  • 1970-01-01
  • 2017-04-16
相关资源
最近更新 更多