在MongoDB中按日期查询日期时间
问题描述:
我有我的mongoDB中包含日期时间和其他值的对象的集合。 我该如何去查询按日期时间查询对象,时间戳设置为9点?在MongoDB中按日期查询日期时间
所以,如果我有以下集合...
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的重复,我认为这是部分正确的,但它也比我需要的更复杂。
我不需要分组或任何这种性质,我只是想要一个查询,告诉我哪些文档存在包含此时间戳。
答
您可以使用聚合管道将转换为匹配的转换值。例如:
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
步骤输出 - 对于基础集合中的每个文档 - 包含_id
,date
和一个名为timePart
的新属性的文档,该属性已使用date属性中的时间部分填充。然后$match
步骤将这些文档与您的过滤条件相匹配(在您的示例中,这是09:00:00:000
即上午9点),然后将匹配的文档转发到下一步,再次使用$project
运算符放弃timePart属性,因为我假设,这只与saerching相关,不应包含在最终结果中。
其分解,第一步的输出是这样的:
{
"_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"
},
...
第二步排除与id: 2
文件,因为它timePart不匹配09:00:00.000
然后将文档与id: 1
转发到第三该阶段然后选择 - 从第2步转发这些文件 - 领域_id
和date
从而给你:
{
"_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")
}
注:此approac h在应用匹配阶段之前必须将的日期属性改为文档,如果对于您来说这太令人担忧了,那么您可能需要重新考虑如何持续保存这些数据。
我对MongoDB相当陌生,所以让我来总结一下,看看我是否正确地得到这个结果:对于每个文档,你取日期,格式化它,把它变成一个字符串,然后到一个时间部分,然后你将它匹配到另一个由字符串组成的时间部分? – SpiritBH
我已经更新了答案,以解释聚合管道的性质。希望有所帮助。 – glytching
谢谢你,这个工作就像一个魅力,你帮助我更好地理解这一点。 – SpiritBH