如何从AggregationOutput映射到POJO?

时间:2013-05-20 21:47:31

标签: java mongodb aggregation-framework mongodb-java

对于一个复杂的查询,我下载到MongoDB Java API(对于我的大多数东西使用Spring-data),我使用BasicDBObjects编写了一个聚合语句。

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(我的聚合中没有$ group)。

如果我将Criteria API用于查询,我会得到一个User对象。在AggregationOutput#results()中,我有一个DBObject。

有没有办法调用内部用于直接将DBObject转换为我的POJO的转换器?

我试过

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

但是它引发了一个异常,它无法实例化java.util.List。这是有道理的,因为那是一个界面。

有什么想法吗?

谢谢!

克里斯托弗。

2 个答案:

答案 0 :(得分:0)

我建议使用一个单独的类(AggregatedUser.class),您可以在其中直接映射输出结果而不是用户POJO映射。

为什么我会这样做有一些原因:

  • 构建它很容易
  • 不要丢弃将来可能有用的聚合输出的元信息
  • 一旦开始使用$project,您将需要它

关于执行此操作的弹簧适配器,我不知道它是可能的。我可能错了。

<磷>氮

答案 1 :(得分:0)

来自man page of unwind

  

$ unwind为展开的数组的每个成员返回一个文档   在每个源文档中。

你写道:

  

这种聚合的结果仍然非常适合   在我的POJO中(我的聚合中没有$ group)。

这是一个错误的假设!放松确实会影响所返回文档的结构,并且您的POJO不再适合结果。

在这种情况下,您正在展开vitals数组。返回的文档不包含生命体征列表。相反,每个用户文档都有一个生命体对象。这种结构差异导致映射器失败,因为它期望一个生命体征列表,但却得到了一个重要的对象。