2

对于一个复杂的查询,我使用了 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。这是有道理的,因为那是一个界面。

有任何想法吗?

谢谢!

克里斯托夫。

4

2 回答 2

1

来自unwind 的手册页

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

你写道:

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

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

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

于 2013-06-24T13:44:33.197 回答
0

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

我会这样做有一些原因:

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

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

N。

于 2013-05-21T15:17:51.340 回答