首页 > 解决方案 > 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"
        }
      ]

}
]

请建议。

标签: mongodb

解决方案


您可以使用limitskip 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
}

推荐阅读