首页 > 解决方案 > 在提供的多个日期范围之间获取 mongo 结果

问题描述

我有个问题。我需要从 MongoDB 中获取记录并将它们绘制在图表中。我需要以这样一种方式获取数据,即从 MongoDB 中获取日期范围内的记录。日期范围是这样的

1.    start date 2018-07-10 05:00:00,  end date: 2018-07-11 04:59:59
2.    start date 2018-07-11 05:00:00,  end date: 2018-07-12 04:59:59
3.    start date 2018-07-12 05:00:00,  end date: 2018-07-13 04:59:59
4.    start date 2018-07-13 05:00:00,  end date: 2018-07-14 04:59:59

数据样本:

    {
       "_id" : ObjectId("5b488f7631b9a41d733d5360"),
       "user" : 8,
       "event" : 2,
       "checkedIn" : 0,
       "TotalTime" : 235,
       "CheckedInAt" : 1531482213,
       "user_event" : [ 
           {
               "date" : ISODate("2018-07-13T11:43:33.496Z"),
               "totalTime" : 235,
               "CheckedInAt" : 1531482213
           },
           {
               "date" : ISODate("2018-07-12T00:43:33.496Z"),
               "totalTime" : 235,
               "CheckedInAt" : 1531482213
           },
           {
               "date" : ISODate("2018-07-10T11:43:33.496Z"),
               "totalTime" : 235,
               "CheckedInAt" : 1531482213
           }
       ]
    },
{
       "_id" : ObjectId("5b488f7631b9a41d733d5360"),
       "user" : 8,
       "event" : 3,
       "checkedIn" : 0,
       "TotalTime" : 235,
       "CheckedInAt" : 1531482213,
       "user_event" : [ 
           {
               "date" : ISODate("2018-07-13T11:43:33.496Z"),
               "totalTime" : 235,
               "CheckedInAt" : 1531482213
           },
           {
               "date" : ISODate("2018-07-12T00:43:33.496Z"),
               "totalTime" : 235,
               "CheckedInAt" : 1531482213
           },
           {
               "date" : ISODate("2018-07-10T11:43:33.496Z"),
               "totalTime" : 235,
               "CheckedInAt" : 1531482213
           }
       ]
    },
{
       "_id" : ObjectId("5b488f7631b9a41d733d5360"),
       "user" : 10,
       "event" : 2,
       "checkedIn" : 0,
       "TotalTime" : 235,
       "CheckedInAt" : 1531482213,
       "user_event" : [ 
           {
               "date" : ISODate("2018-07-13T11:43:33.496Z"),
               "totalTime" : 235,
               "CheckedInAt" : 1531482213
           },
           {
               "date" : ISODate("2018-07-12T00:43:33.496Z"),
               "totalTime" : 235,
               "CheckedInAt" : 1531482213
           },
           {
               "date" : ISODate("2018-07-10T11:43:33.496Z"),
               "totalTime" : 235,
               "CheckedInAt" : 1531482213
           }
       ]
    }

user_event是为具有指定事件 ID 的特定用户保存记录的子文档。如果用户再次参加相同的活动,那么他们的记录会堆积在user_event子文档中。我想获取这些记录。

我需要按照提供给他们的日期的顺序来获取这些记录。例如,如果数据位于日期 4 之前,则结果中包含的日期开始日期和结束日期以及位于它们之间的数据。这是我当前的聚合查询(Mongodb 3.4)。它给了我日期格式的记录数组%Y-%m-%d。并event_attended_date包含上述日期格式的特定数据的所有日期

db.getCollection('collectionName').aggregate(
     {
            "$unwind": "$user_event"
        }, {
            "$match": {
                "$and": [{
                        "user_event.date": {
                            "$lte": ISODate('2018-07-14T04:59:590Z'),
                            "$gte": ISODate('2018-07-10T05:00:000Z')
                        }
                    },
                    {
                        "event": 1
                    }
                ]
            }
        }, {
            "$match": {
                "user": {
                    "$nin": [1, 2]
                }
            }
        }, {
            "$group": {
                "_id": {
                    "$dateToString": {
                        "format": "%Y-%m-%d",
                        "date": "$user_event.date"
                    }
                },
                "TotalTime": {
                    "$sum": "$user_event.TotalTime"
                },
                "userAttended": {
                    "$sum": 1
                },
                "event_attended_date": {
                    "$push": "$user_event.date"
                }
            }
        }, {
            "$project": {
                "date": "$_id",
                "TotalTime": 1,
                "userAttended": 1,
                "event_attended_date": 1
            }
        });

这是我当前的输出(显示较少的记录)。我希望每个 /* 记录 */ 包含提供的日期范围内的记录。可能吗?

  /* 1 */
{
    "_id" : "2018-07-10",
    "TotalTime" : 2436,
    "userAttended" : 3.0,
    "event_attended_date" : [ 
        ISODate("2018-07-10T02:46:32.861Z"), 
        ISODate("2018-07-10T01:36:50.799Z"), 
        ISODate("2018-07-10T00:47:35.402Z")
    ],
    "date" : "2018-07-10"
}

/* 2 */
{
    "_id" : "2018-07-09",
    "TotalTime" : 145,
    "userAttended" : 2.0,
    "event_attended_date" : [ 
        ISODate("2018-07-09T15:43:24.071Z"), 
        ISODate("2018-07-09T20:23:22.205Z")
    ],
    "date" : "2018-07-09"
}

我希望记录像这样显示

{
        "_id" : "2018-07-09",
        "TotalTime" : 145, -- sum of their total time
        "userAttended" : 4, -- sum of unique user attended
        "event_attended_date" : [ -- if the above 2 records are accurate then I don't need this element.
            ISODate("2018-07-09T15:43:24.071Z"), 
            ISODate("2018-07-09T20:23:22.205Z")
        ],
        "startDate" : "2018-07-09 05:00:00",
        "endDate" : "2018-07-10 04:59:59",

    }

稍后我将使用 PHP 作为后端来操作这些记录。

标签: mongodb

解决方案


这是一个按日期范围过滤的集合中查找记录的示例

Collection.find({
    created_at: {
        $gte: ISODate("2010-04-29T00:00:00.000Z"),
        $lt: ISODate("2010-05-01T00:00:00.000Z")
    }
})

推荐阅读