我有一个名为用户的集合,其中包含名为消息的嵌入式文档。嵌入式文档消息包含消息对象的数组,如下所示:
{
"_id" : ObjectId("58e09daa192216e39fd85433"),
"userId" : "user123",
"message" : [
{
"messageId" : "5277941e-9d84-46c3-b927-ef33abbf35f2",
"dateCreated" : 1491115000,
"body" : "howdy?",
"type" : "text"
},
{
"messageId" : "c2ce0480-bc0d-4393-89d4-27174d323b98",
"dateCreated" : 1491119000,
"body" : "i've problem with my account. can you help?",
"type" : "text"
},
{
"messageId" : "45b2593c-a960-4066-8723-db2531dd8bab",
"dateCreated" : 1491100000,
"body" : "this is urgent",
"type" : "text"
}
]
}
我的目标是根据 dateCreated 键对嵌入式文档消息进行排序。我需要将这个mongo查询转换为Spring Data MongoDB:
db.user.aggregate(
{$unwind: "$message"},
{$match: {userId: "user123"}},
{$sort: {"message.dateCreated": 1}},
{$group: {_id: "$_id", "message": {"$push": "$message"}}})
我已尝试以下代码,但仍然收到错误:
AggregationOperation unwind = Aggregation.unwind("message");
AggregationOperation match = Aggregation.match(Criteria.where("userId").in("user123"));
AggregationOperation sort = Aggregation.sort(Direction.ASC, "message.dateCreated");
AggregationOperation group = Aggregation.group("userId", "message");
Aggregation aggregation = Aggregation.newAggregation(unwind, match, sort, group);
AggregationResults<User> groupResults = mongoTemplate.aggregate(aggregation, User.class, User.class);
错误:
无法实例化[java.util.List]:指定的类是一个接口
用户类:
@Document(collection="user")
public class User {
@Id
private String id;
private String userId;
@Field("message")
@DBRef
private List<Message> message;
//constructor, getter, setter
}
消息类:
@Document
public class Message {
private String messageId;
private long dateCreated;
private String body;
private String type;
//constructor, getter, setter
}
提示:
根据我的研究,我非常确定我需要使用 GroupOperationBuilder group = Aggregation.group(&#34; userId&#34;)。推(&#34;消息&#34;)但我真的不知道如何继续这样做,因为AggregationResults不允许我在 mongoTemplate.aggregate()
中使用它答案 0 :(得分:0)
优化查询将是:
db.user.aggregate(
{$match: {userId: "user123"}},
{$unwind: "$message"},
{$sort: {"message.dateCreated": 1}},
{$group: {_id: "$_id", "message": {"$push": "$message"}}});
如果您首先使用此给定查询,它将过滤符合您条件的文档,然后它将展开已过滤的文档。
答案 1 :(得分:0)
您的实体类似乎是错误的。为什么Message有@DBRef
作为注释?
在我看来应该是这样的:
@Document(collection="user")
public class User {
@Id
private String id;
private String userId;
@Field("message")
private List<Message> message;
//constructor, getter, setter
}
public class Message {
private String messageId;
private long dateCreated;
private String body;
private String type;
//constructor, getter, setter
}