I have a collection named User which contains embedded document called Message. The embedded document Message contains array of message object as below :
我有一个名为User的集合,其中包含名为Message的嵌入式文档。嵌入式文档消息包含消息对象数组,如下所示:
{
"_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"
}
]
}
My objective is to sort embedded document Message based on dateCreated key. I need to translate this mongo query into Spring Data MongoDB :
我的目标是基于dateCreated键对嵌入的文档消息进行排序。我需要将这个mongo查询翻译成Spring Data MongoDB:
db.user.aggregate(
{$unwind: "$message"},
{$match: {userId: "user123"}},
{$sort: {"message.dateCreated": 1}},
{$group: {_id: "$_id", "message": {"$push": "$message"}}})
I've tried the following codes but still getting error :
我试过下面的代码,但还是有错误:
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);
Error :
错误:
Failed to instantiate [java.util.List]: Specified class is an interface
实例化(java.util失败。指定的类是一个接口
User class :
用户类:
@Document(collection="user")
public class User {
@Id
private String id;
private String userId;
@Field("message")
@DBRef
private List<Message> message;
//constructor, getter, setter
}
Message class :
信息类:
@Document
public class Message {
private String messageId;
private long dateCreated;
private String body;
private String type;
//constructor, getter, setter
}
Hint :
提示:
Based on my research, I'm pretty sure that I need to use GroupOperationBuilder group = Aggregation.group("userId").push("message") but I don't really know how to proceed with this as AggregationResults will not allow me to use it in the mongoTemplate.aggregate()
基于我的研究,我非常确定我需要使用GroupOperationBuilder组= aggreg. group(“userId”).push(“消息”),但是我不知道如何进行这个操作,因为聚合结果将不允许我在mongotemplate .聚合()中使用它。
2 个解决方案
#1
0
Optimize query will be:
优化查询将:
db.user.aggregate(
{$match: {userId: "user123"}},
{$unwind: "$message"},
{$sort: {"message.dateCreated": 1}},
{$group: {_id: "$_id", "message": {"$push": "$message"}}});
If you use this given query first it will filter the documents that match your criteria, then it will unwind the filtered documents.
如果您首先使用这个给定的查询,它将过滤符合您的条件的文档,然后它将展开已过滤的文档。
#2
0
It seems like your entity classes are wrong. Why does Message have @DBRef
as annotation?
似乎您的实体类是错误的。为什么消息有@DBRef作为注释?
In my opinion it should be like that:
我认为应该是这样:
@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
}
#1
0
Optimize query will be:
优化查询将:
db.user.aggregate(
{$match: {userId: "user123"}},
{$unwind: "$message"},
{$sort: {"message.dateCreated": 1}},
{$group: {_id: "$_id", "message": {"$push": "$message"}}});
If you use this given query first it will filter the documents that match your criteria, then it will unwind the filtered documents.
如果您首先使用这个给定的查询,它将过滤符合您的条件的文档,然后它将展开已过滤的文档。
#2
0
It seems like your entity classes are wrong. Why does Message have @DBRef
as annotation?
似乎您的实体类是错误的。为什么消息有@DBRef作为注释?
In my opinion it should be like that:
我认为应该是这样:
@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
}