2013-05-20 97 views
2

對於一個複雜的查詢我下降到MongoDB Java API(使用Spring-data的大部分東西),我寫了一個使用BasicDBObjects的聚合語句。如何從AggregationOutput映射到POJO?

DBCollection users = mongoOperations.getCollection("users"); 

    AggregationOutput aggregationOutput = users.aggregate(
      new BasicDBObject("$match", new BasicDBObject("_id", userId)), 
      new BasicDBObject("$project", new BasicDBObject("userProfile.vitals", 1)), 
      new BasicDBObject("$unwind", "$userProfile.vitals"), 
      new BasicDBObject("$match", new BasicDBObject("userProfile.vitals.type", type.name())), 
      new BasicDBObject("$sort", new BasicDBObject("userProfile.vitals.observationDate", -1)), 
      new BasicDBObject("$limit", 1) 
    ); 

此查詢適用,我的問題與本聲明無關。

這個聚合的結果仍然完全符合我的POJO(我的聚合中沒有$組)。

如果我會使用Criteria API查詢,我會得到一個User對象。在AggregationOutput#results()我有一個DBObject。

有沒有辦法調用轉換器,將內部用於將DBObject直接轉換爲我的POJO?

我試圖

mongoTemplate.getConverter().read(User.class,result); 

而是拋出一個異常,這是不能夠實例化的java.util.List。這是有道理的,因爲這是一個界面。

任何想法?

謝謝!

Kristof。

回答

0

man page of unwind

$放鬆返回一個文件爲每個源文檔中的退繞陣列 的每一個成員。

你寫道:

此聚集的結果,仍然是完全符合 在我的POJO(我總沒有$組)。

這是一個錯誤的假設!展開確實影響返回文檔的結構,並且您的POJO不再適合結果。

在這種情況下,您展開vitals數組。返回的文檔不包含生命體列表。相反,每個用戶文檔都有一個生命體。這種結構差異導致映射器失敗,因爲它期望生命體列表,而是獲得重要的對象。

0

我會建議使用一個單獨的類(AggregatedUser.class),您可以直接映射輸出結果而不是用戶POJO映射。

這裏有一些原因,我會做到這一點:

  • 可以很容易地構建它
  • 不要丟棄聚集輸出,可以在未來
  • 一次是有用的元信息你開始使用$project你將需要它

關於彈簧適配器執行此操作,我不知道這是可能的。但我可能錯了。

N.