在MongoDB中按时间查询日期时间

时间:2017-07-31 13:16:10

标签: mongodb datetime mongodb-query

我的mongoDB中有一组对象,其中包含其他值的日期时间。 我将如何通过datetime查询对象,其中时间戳设置为9 o' clock?

所以,如果我有以下收藏......

id : 1, date : ISODate("2017-07-16T09:00:00.000+0000")
id : 2, date : ISODate("2017-01-17T07:00:00.000+0000")
id : 3, date : ISODate("2017-07-27T09:00:00.000+0000")
id : 4, date : ISODate("2017-03-20T09:00:00.000+0000")
id : 5, date : ISODate("2017-03-07T10:00:00.000+0000")
id : 6, date : ISODate("2017-07-04T11:00:00.000+0000")

返回值应为......

id : 1, date : ISODate("2017-07-16T09:00:00.000+0000")
id : 3, date : ISODate("2017-07-27T09:00:00.000+0000")
id : 4, date : ISODate("2017-03-20T09:00:00.000+0000")

我对MongoDB相当新,对Js没有太多经验,所以请尽量保持简单。为此,Neil Lunn将此问题标记为重复 This Question,我认为这部分是正确的,但它也比我需要的更复杂。

我不需要分组或任何性质的东西,我只想要一个查询,告诉我哪些文档存在包含此时间戳。

1 个答案:

答案 0 :(得分:1)

您可以使用聚合管道转换the date to its timepart,然后匹配该转换后的值。例如:

db.collection.aggregate([
    {
        $project: {
            timePart: {$dateToString: { format: "%H:%M:%S:%L", date: "$date"}},     
            date: 1

        }
    },
    {
        $match: {
            timePart: '09:00:00:000'
        }
    },
    {
        $project: {
            date: 1
        }
    }
])

您可以将此视为管道;第一个$project步骤的输出成为$match步骤的输入。 $project步骤输出 - 用于基础集合中的每个文档 - 包含_iddate和名为timePart的新属性的文档,该文档已填充时间部分来自日期属性。然后,$match步骤会根据您的过滤条件匹配这些文档(在您的示例中,这是09:00:00:000,即上午9点),然后将匹配的文档转发到使用{{1}的下一步骤运算符再次丢弃timePart属性,因为我认为这只与saerching有关,不应该包含在最终结果中。

分解,第一步的输出如下:

$project

第二步将文档排除{ "_id" : 1, date : ISODate("2017-07-16T09:00:00.000+0000"), timePart: "09:00:00.000" }, { "_id" : 2, date : ISODate("2017-01-17T07:00:00.000+0000"), timePart: "07:00:00.000" }, ... ,因为其timePart与id: 2不匹配,然后将文档与09:00:00.000转发到第三个阶段,然后从第二个转发的文档中选择 - 第2步 - 字段id: 1_id从而为您提供:

date

注意:此方法必须在应用匹配阶段之前转换每个文档的日期属性,如果这对您来说效率低下,那么您可能想重新考虑如何持久保存此数据