2013-05-20 67 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.