mongodb - Mongo在文档的嵌套数组中分组和分页
问题描述
我的 MongoDb 中有以下集合,
[
{
"groupName" : "testName",
"participants" : [
{
"participantEmail" : "test@test.com",
"lastClearedDate" : 12223213123
},
{
"participantEmail" : "test2@test.com",
"lastClearedDate" : 1234343243423
}
],
"messages" : [
{
_id: 283891238912,
message: "this was on 13th 10 -1",
sender: "test@test.com"
},{
_id: 283891238913,
message: "this was on 13th 10 -2",
sender: "test2@test.com"
},{
_id: 283891238914,
message: "this was on 14th 10 -1",
sender: "test@test.com"
},{
_id: 283891238915,
message: "this was on 14th 10 -2",
sender: "test2@test.com"
},{
_id: 283891238916,
message: "this was on 14th 10 -3",
sender: "test@test.com"
},{
_id: 283891238917,
message: "this was on 14th 10 -4",
sender: "test2@test.com"
}
]
}
]
我想显示按日期分组的最新 20 条消息,最旧的第一个带有分页。我通过以下查询按结果分组,
ChatGroup.aggregate([
{
$match: {
groupName: groupName,
"messages.time": { $gte: messagesFrom }
}
},
{ $unwind: "$messages" },
{ $sort: { "messages.time": 1 } },
{ $match: { "messages.time": { $gte: messagesFrom } } },
{
$group: {
_id: {
year: { $year: { $add: [new Date(0), "$messages.time"] } },
month: { $month: { $add: [new Date(0), "$messages.time"] } },
day: { $dayOfMonth: { $add: [new Date(0), "$messages.time"] } }
},
messages: { $push: "$messages" },
count: { $sum: 1 }
}
}
])
我将 splice 与我的 push 运算符一起使用,将它与 sort 运算符链接,但没有运气。
我还尝试按以下顺序链接操作过滤器、展开、排序、拼接、分组依据。但结果并不如我所愿。
例如 - 考虑我的页面大小是 4 那么输出应该是,
[{"_id":{
"year":2018,
"month":10,
"day":13
},
"messages":[
{
_id: 283891238912,
message: "this was on 13th 10 -1",
sender: "test@test.com"
},{
_id: 283891238913,
message: "this was on 13th 10 -2",
sender: "test2@test.com"
}
]
},
{"_id":{
"year":2018,
"month":10,
"day":14
},
"messages":[
{
_id: 283891238914,
message: "this was on 14th 10 -1",
sender: "test@test.com"
},{
_id: 283891238915,
message: "this was on 14th 10 -2",
sender: "test2@test.com"
}
]
}
]
对于下一个请求,
[
"_id":{
"year":2018,
"month":10,
"day":14
},
"messages":[
{
_id: 283891238916,
message: "this was on 14th 10 -3",
sender: "test@test.com"
},{
_id: 283891238917,
message: "this was on 14th 10 -4",
sender: "test2@test.com"
}
]
}
]
请建议。
解决方案
您可以使用limit
和skip 0 to 4
。
db.getCollection('test').aggregate([
{
$match: {
"groupName": "testName"
}
},
{ $unwind: "$messages" },
{ $match: { "messages.time": { $gte: 1539863050000 } } },
{ $sort: { "messages.time": 1 } },
{ $skip: 4 },
{ $limit: 4 },
{
$group: {
_id: {
year: { $year: { $add: [new Date(0), "$messages.time"] } },
month: { $month: {$add: [new Date(0), "$messages.time"] } },
day: { $dayOfMonth: { $add: [new Date(0), "$messages.time"] } }
},
messages: { $push: "$messages" },
count: { $sum: 1 }
}
}
])
输出:
第一个请求:
/* 1 */
{
"_id" : {
"year" : 2018,
"month" : 10,
"day" : 19
},
"messages" : [
{
"time" : NumberLong(1539949710000),
"message" : "this was on 19th 10 -4",
"sender" : "test2@test.com"
},
{
"time" : NumberLong(1539949720000),
"message" : "this was on 19th 10 -3",
"sender" : "test@test.com"
}
],
"count" : 2.0
}
/* 2 */
{
"_id" : {
"year" : 2018,
"month" : 10,
"day" : 18
},
"messages" : [
{
"time" : NumberLong(1539863150000),
"message" : "this was on 18th 10 -2",
"sender" : "test2@test.com"
},
{
"time" : NumberLong(1539863550000),
"message" : "this was on 18th 10 -1",
"sender" : "test@test.com"
}
],
"count" : 2.0
}
第二个要求:
/* 1 */
{
"_id" : {
"year" : 2018,
"month" : 10,
"day" : 19
},
"messages" : [
{
"time" : NumberLong(1539949730000),
"message" : "this was on 19th 10 -2",
"sender" : "test2@test.com"
},
{
"time" : NumberLong(1539949750000),
"message" : "this was on 19th 10 -1",
"sender" : "test@test.com"
}
],
"count" : 2.0
}
推荐阅读
- python - x509 证书验证 Python
- c# - SQLite 与 WPF 应用程序部署
- reactjs - 在反应中验证蚂蚁设计 InputNumber 的最大长度
- spring-boot - 在控制器中处理可为空的 UUID - SpringBoot 和 Postgres
- dynamics-crm - 在 CRM 设计中,是否必须在请求更改地址时强制更新电话号码?
- r - 在一张图像中合并几个并排的图,直到某个给定的上限
- ansible - 如何阻止ansible跳到第二个任务,直到第一个任务成功执行?
- postgresql - 如何在 PostgreSQL 中切换用户?我的意思是作为 PostgreSQL 中的另一个现有用户登录
- python - MultiIndexed pandas 数据框认为输入是唯一的
- amazon-web-services - Scala:获取 URL 参数