+-
从nodejs查询MongoDB中的日期范围

我试图让所有用户在指定的日期范围内,我的数据库结构如下所示:

{
    _id : ObjectId("58b545d4b57eeb2cc456248a"),
    "attendance" : [ 
        {
            "2017-03-16" : ["58c108b9ebd9ae24dca81634"],
            "2017-03-17" : ["58c108b9ebd9ae24dca81634"],
            "2017-03-18" : ["58c108b9ebd9ae24dca81634"],
            "2017-03-19" : ["58c108b9ebd9ae24dca81634"],
            "2017-03-20" : ["58c108b9ebd9ae24dca81634","58c108b9ebd9ae24dca81635"]
        }, 
        {
            "2017-03-17" : ["58c108b9ebd9ae24dca81634"],
            "2017-03-18" : ["58c108b9ebd9ae24dca81634"],
            "2017-03-19" : ["58c108b9ebd9ae24dca81634"],
            "2017-03-20" : ["58c108b9ebd9ae24dca81634","58c108b9ebd9ae24dca81635"]
        }
    ]
    .......
}

并查询它:

routes.find({_id: ObjectId("58b545d4b57eeb2cc456248a"), $or:[{'attendance[0]' : {$gte: '2017-03-17' }}, {'attendance[1]': {$gte: '2017-03-17'}}]})

但它没有取得任何结果。

3
投票

看起来您的日期被保存在键(字段名称)中;但MongoDB仅用于查询字段值中保存的数据。我建议你将数据重组为以下内容:

{
    _id : ObjectId("58b545d4b57eeb2cc456248a"),
    "attendance" : [ 
        {
            "dateitems" : [
                {"when" : ISODate("2017-03-16"), "who" : [ObjectId("58c108b9ebd9ae24dca81634")]},
                {"when" : ISODate("2017-03-17"), "who" : : [ObjectId("58c108b9ebd9ae24dca81634")]},
                {"when" : ISODate("2017-03-18"), "who" : : [ObjectId("58c108b9ebd9ae24dca81634")]},
                {"when" : ISODate("2017-03-19"), "who" : : [ObjectId("58c108b9ebd9ae24dca81634")]},
                {"when" : ISODate("2017-03-20"), "who" : : [ObjectId("58c108b9ebd9ae24dca81634"),ObjectId("58c108b9ebd9ae24dca81635")]}
            ]
        }, 
        {
            "dateitems" : [
                {"when" : ISODate("2017-03-17"), "who" : [ObjectId("58c108b9ebd9ae24dca81634")]},
                {"when" : ISODate("2017-03-18"), "who" : [ObjectId("58c108b9ebd9ae24dca81634")]},
                {"when" : ISODate("2017-03-19"), "who" : [ObjectId("58c108b9ebd9ae24dca81634")]},
                {"when" : ISODate("2017-03-20"), "who" : [ObjectId("58c108b9ebd9ae24dca81634",ObjectId("58c108b9ebd9ae24dca81635")]}
            }
        }
    ]
    .......
}

使用这种数据结构,您可以查询以获得所需的输出,例如:

routes.aggregate([
    {$match: { _id: ObjectId("58b545d4b57eeb2cc456248a")}},
    {$match: {"attendance.dateitems.when" : {$gt: ISODate("2017-03-17")}}}
})

以下是我在重组中改变的一些要点:

而不是字符串,每个ObjectId引用都在真正的ObjectID type中;这将允许有效的比较和查找。 而不是字符串,每个日期都使用ISODate格式标准化的Date data type;这将允许有效的比较,如$ gt。 出勤数据已经扩展为一个dateitem对象数组,每个对象都有一个日期字段和一个引用对象的字段(我猜这些是人们出席的ID);这样,每个数据值都存储为field value - 而不是字段名。
-1
投票

在node.js中,我们可以通过new Date()查询ISODate来查找日期范围数据

db.collectionName.find({ 
   'updatedAt': {
          $gte: new Date('2019-04-19T14:16:04.065Z'),
          $lte: new Date('2019-04-19T14:16:04.070Z')
        }})