【问题标题】:query date range in MongoDB from nodejs从nodejs查询MongoDB中的日期范围
【发布时间】:2017-03-20 09:29:01
【问题描述】:

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

{
    _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'}}]})

但它没有获取任何结果。

【问题讨论】:

    标签: node.js mongodb date-range


    【解决方案1】:

    您的日期似乎保存在 keys(字段名)中;但 MongoDB 仅用于查询字段 values 中保存的数据。我建议您将数据重组为如下形式:

    {
        _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")}}}
    })
    

    以下是我在重组过程中改变的一些关键点:

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

    【讨论】:

    • 感谢您的宝贵意见,您能帮我看看我应该如何编辑当前数据库并将其保存为新格式,因为我是新手
    • @warl0ck 这是一个大问题,如果不知道您的数据库是如何创建和维护的,就不可能可靠地回答。如果它在单个应用程序的控制下,那么一种明智的方法可能是定义一个数据迁移过程,将现有数据转换为新格式。但是,您还需要更改应用程序的数据库命令,以便以新格式存储新数据。
    • 是的,我知道我必须在 nodejs 模板中更改其保存方式和模型的数据格式,但如何更改以便我可以搜索日期范围。 PS:我有所有的访问权限。
    • 从 nodejs 我得到 ReferenceError: ISODate is not defined
    【解决方案2】:

    在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')
            }})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-09
      • 2018-09-18
      • 1970-01-01
      • 1970-01-01
      • 2014-09-29
      • 2014-11-28
      • 2021-01-03
      相关资源
      最近更新 更多