2014-06-12 87 views
0

使用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的對象。全文檔是整個文檔。

我想知道是否可以用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

爲什麼不也一樣嗎?什麼是你真正的Java代碼,你發現有什麼區別? –

+0

感謝您的回覆。我會在我的問題 – Chessman

回答

3

我以前見過這種事情,它不僅限於變量名稱,如$$ROOT。 Spring數據擁有關於如何在流水線中映射文檔的「屬性」的自己的想法。另一個常見問題是簡單地投射一個新的或計算的字段,它基本上有一個新的「屬性」名稱,它不會被識別。

也許最好的方法是從使用幫助程序類和方法「下臺」並將管道構建爲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(); 

主要的是從被獲得的方式和建設管道,因爲它應該是免費的施加的限制傭工移開。

+0

中添加我的java代碼感謝您的意見。 「另一個常見問題是簡單地投射一個新的或計算的字段,它基本上有一個新的」屬性「名稱,它不會被識別。」 您是否有一個例子來說明您希望能夠使用Spring Data MongoDB做什麼? –

+0

@ThomasDarimont我遇到過幾個。我現在的就寢時間。如果有地方可以提交JIRA問題或任何錯誤跟蹤,請告訴我。如果需要,我會挖掘一個案例並進行測試。 –

+0

你可以在這裏找到Spring Data MongoDB的JIRA:https://jira.spring.io/browse/DATAMONGO –

4

我們創建了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") // 
); 
+0

非常感謝您的幫助 – Chessman