我有一个执行以下步骤的mongo DB聚合管道:
简而言之,此管道从按指定统计信息排序的用户统计信息列表返回页面。每个用户可以有多个stats对象,因此我分组以仅返回每个用户的最新stats对象。
在Mongo Shell中,这看起来像:
db.getCollection("stats").aggregate(
[
{ "$sort" : { "Timestamp" : -1.0 } },
{
"$group" : {
"_id" : "$UserId",
"UserId" : { "$last" : "$UserId" },
"StatsOverall" : { "$last" : "$StatsOverall" },
"Timestamp" : { "$last" : "$Timestamp" }
}
},
{ "$sort" : { "StatsOverall.Rank" : -1.0 } },
{ "$skip" : specifiedPageNumber },
{ "$limit" : specifiedNumResultsPerPage }
]
);
这很好。
我现在想修改此查询,以便能够按名称搜索用户,并获取包含该用户的整个页面。 (这是排行榜的)。因此,如果用户位于页首横幅的第5页,则我想返回第5页的整个页面。
但是,我遇到的解决方案很麻烦,它不需要我将所有用户都加载到内存中并在其中分页(这真是个好主意),或者来回遍历数据库(通过页面来回访问)(几乎一样糟糕)。
是否可以通过某种方式修改聚合管道以在数据库级别执行所有这些操作?
编辑:根据要求,添加了一些示例数据和预期结果。
样本数据看起来像这样...我省略了一些不相关的字段。初始数据是用户统计信息的集合,其中每个用户可以有多个对象。我现有的管道会为每个用户返回1个最新的统计信息对象,并按指定的统计信息名称排序。
{
"_id" : "5c611e71ab0ffc430410e0ba",
"UserId" : "5c611e71ab0ffc430410e0ba",
"StatsOverall" : {
"Rank" : NumberInt(1000),
"GamesLost" : NumberInt(30),
"GamesWon" : NumberInt(50)
}
"Timestamp" : "2019-02-10T21:35:06.599Z"
}
// ----------------------------------------------
{
"_id" : "5c6238658966ae5860795879",
"UserId" : "5c6238658966ae5860795879",
"StatsOverall" : {
"Rank" : NumberInt(413),
"GamesLost" : NumberInt(2),
"GamesWon" : NumberInt(141),
},
"Timestamp" : "2019-02-10T21:35:06.599Z"
}
// many objects like this
预期结果如下:
{
"_id" : "5c611e71ab0ffc430410e0ba",
"UserId" : "5c611e71ab0ffc430410e0ba",
"StatsOverall" : {
"Rank" : NumberInt(1000),
"GamesLost" : NumberInt(30),
"GamesWon" : NumberInt(50)
}
"Timestamp" : "2019-02-10T21:35:06.599Z"
}
它返回与对象类型完全相同的对象,排序方式与现有管道相同,但是我只想返回用户所在的页面。在示例结果中,假设页面大小仅为每页1个结果。因此,结果将包含具有给定UserId
的用户所在的1页。在我的示例结果中,该ID为5c611e71ab0ffc430410e0ba
。