我有一组消息,其中包含字段user_id,created_time和content。给定一个user_id列表,我想找回一个消息列表,其中每个user_id包含一条关于该用户的最新消息。我想在mongo中使用一个不同的命令和sort,但似乎没有得到支持。有没有办法在mongo中使用单个查询执行此操作?
答案 0 :(得分:2)
MongoDB有Aggregation framework,您可以将其用于需要对集合中的数据进行操作的任务
考虑以下数据集
> db.messages.find().pretty()
{
"_id" : ObjectId("52ecb77486d35a12f3552aa1"),
"user_id" : "fred",
"create_date" : ISODate("1392-09-21T00:00:00Z")
}
{
"_id" : ObjectId("52ecb79286d35a12f3552aa2"),
"user_id" : "fred",
"create_date" : ISODate("1392-06-01T00:00:00Z")
}
{
"_id" : ObjectId("52ecb7a386d35a12f3552aa3"),
"user_id" : "marty",
"create_date" : ISODate("1393-04-06T00:00:00Z")
}
{
"_id" : ObjectId("52ecb7af86d35a12f3552aa4"),
"user_id" : "marty",
"create_date" : ISODate("1386-02-12T00:00:00Z")
}
因此,在将其传递给汇总时,我们希望对user_id
进行分组并获取最新内容或maximum
create_date
> db.messages.aggregate([
{ $group: { _id: { user_id: "$user_id" }, create_date: { $max: "$create_date" }} }
])
{
"result" : [
{
"_id" : {
"user_id" : "marty"
},
"create_date" : ISODate("1393-04-06T00:00:00Z")
},
{
"_id" : {
"user_id" : "fred"
},
"create_date" : ISODate("1392-09-21T00:00:00Z")
}
],
"ok" : 1
}
这不错,但你可以用 $ project
清理它> db.messages.aggregate([
{ $group: { _id: { user_id: "$user_id" }, create_date: { $max: "$create_date" }} },
{ $project: { _id: 0, user_id: "$_id.user_id", create_date: 1} }
])
{
"result" : [
{
"create_date" : ISODate("1393-04-06T00:00:00Z"),
"user_id" : "marty"
},
{
"create_date" : ISODate("1392-09-21T00:00:00Z"),
"user_id" : "fred"
}
],
"ok" : 1
}
所以它实际上看起来像一个干净的记录。在最新的驱动程序中,聚合返回的值应该是可以迭代的游标。所以结果和使用find一样。
可以找到有关运营商使用的其他文档here。