Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb Mongo查询以按天获取1个带有时间参数的文档_Mongodb_Datetime - Fatal编程技术网

Mongodb Mongo查询以按天获取1个带有时间参数的文档

Mongodb Mongo查询以按天获取1个带有时间参数的文档,mongodb,datetime,Mongodb,Datetime,我无法从数据库中获取所需日期的文档 我的数据库结构如下所示: { date: 2019-10-24T10:00:00.000Z, value: 6 }, { date: 2019-10-24T10:01:03.000Z, value: 6 }, { date: 2019-10-24T10:02:35.000Z, value: 6 }, ... start = new Date('2019-10-22T10:00:00.000Z') end = new Date('201

我无法从数据库中获取所需日期的文档

我的数据库结构如下所示:

{
  date: 2019-10-24T10:00:00.000Z,
  value: 6
},
{
  date: 2019-10-24T10:01:03.000Z,
  value: 6
},
{
  date: 2019-10-24T10:02:35.000Z,
  value: 6
},
...
start = new Date('2019-10-22T10:00:00.000Z')
end = new Date('2019-10-24T10:00:00.000Z)

{
  date: '2019-10-22T09:59:13.000Z',
  value: 10
},
{
  date: '2019-10-23T10:00:00.000Z',
  value: 17
},
{
  date: '2019-10-24T09:58:55.000Z',
  value: 10
}
并尝试获取包含两个参数的查询:

  • 开始日期(结束日期-x天)
  • 结束日期
并且在startDate和endDate之间每天交付1个文档,此文档需要最接近endDate的时间(HH:mm:ss)。 大概是这样的:

{
  date: 2019-10-24T10:00:00.000Z,
  value: 6
},
{
  date: 2019-10-24T10:01:03.000Z,
  value: 6
},
{
  date: 2019-10-24T10:02:35.000Z,
  value: 6
},
...
start = new Date('2019-10-22T10:00:00.000Z')
end = new Date('2019-10-24T10:00:00.000Z)

{
  date: '2019-10-22T09:59:13.000Z',
  value: 10
},
{
  date: '2019-10-23T10:00:00.000Z',
  value: 17
},
{
  date: '2019-10-24T09:58:55.000Z',
  value: 10
}
现在,我有一个聚合函数,它可以为我获取每天的第一个文档:

.aggregate([
    {
      $match: {
        date: { $gte: ISODate('2019-05-26T12:00:00.000Z'), $lte: ISODate('2019-10-26T12:00:00.000Z') }
      }
    },
    {
      $project: {
        _id: 1,
        value: 1,
        docDate: '$date',
        day: {
          '$dayOfMonth': '$date'
        },
        month: {
          '$month': '$date'
        },
        year: {
          '$year': '$date'
        }
      }
    },
    {
      $project: {
        _id: 1,
        value: 1,
        docDate: 1,
        date: {
          '$concat': [
            {
              $substr: ['$year', 0, 4]
            },
            '-',
            {
              $substr: ['$month', 0, 2]
            },
            '-',
            {
              $substr: ['$day', 0, 2]
            }
          ]
        }
      }
    },
    {
      $group: {
        _id: '$date',
        objId: {
          $first: '$_id'
        },
        value: {
          $first: '$value'
        },
        date: {
          $first: '$docDate'
        }
      }
    },
    {
      $project: {
        _id: '$objId',
        value: 1,
        date: 1
      }
    },
    {
      '$sort': {
        date: 1
      }
    }
  ]
)

所以我想这个问题可能就是你想要的

db.records.aggregate([
    { $match: { 
         date: { 
           $gte: ISODate('2019-05-03T12:01:07Z'), 
           $lte: ISODate('2019-05-07T12:01:07Z') 
        }
      }
    },
    { $addFields:  {
         date_string: { $dateToString: { format: "%Y-%m-%d", date: "$date" } }
       }
    },
    { $sort: { date: -1 } },
    { $group: {
        _id: "$date_string",
        my_doc: { $first: "$$ROOT" }
      }
    },
    { $replaceRoot: { newRoot: "$my_doc" } },
    { $project: { date_string: 0 } }, 
    { $sort: { date: 1 } }
])
渠道策略细分:

{ "_id" : ObjectId("5db21090d15e418f2d5b7b4e"), "value" : 3, "date" : ISODate("2019-05-03T12:01:07Z") }
{ "_id" : ObjectId("5db21090d15e418f2d5b7b4f"), "value" : 4, "date" : ISODate("2019-05-04T12:07:07Z") }
{ "_id" : ObjectId("5db21090d15e418f2d5b7b53"), "value" : 5, "date" : ISODate("2019-05-05T12:01:07Z") }
{ "_id" : ObjectId("5db21090d15e418f2d5b7b54"), "value" : 6, "date" : ISODate("2019-05-06T12:01:07Z") }
{ "_id" : ObjectId("5db21090d15e418f2d5b7b55"), "value" : 7, "date" : ISODate("2019-05-07T12:01:07Z") }
>匹配>选择日期范围

考虑的记录范围
  • $addFields-只获取日期字符串,不包含时间。这是$group实际分组所必需的。如果字符串也包含时间,它将无法正确分组

  • $sort date-1=这是分组之前需要的,因此我们可以使用$group中的$first运算符

  • $group—聚合并使用$first选择分组中的项目

  • $replaceRoot-将管道输出转换回原始文档格式

  • $project-删除临时日期字符串字段

  • $sort date 1-将数据按正常排序顺序放回原处

  • 输出:

    { "_id" : ObjectId("5db21090d15e418f2d5b7b4e"), "value" : 3, "date" : ISODate("2019-05-03T12:01:07Z") }
    { "_id" : ObjectId("5db21090d15e418f2d5b7b4f"), "value" : 4, "date" : ISODate("2019-05-04T12:07:07Z") }
    { "_id" : ObjectId("5db21090d15e418f2d5b7b53"), "value" : 5, "date" : ISODate("2019-05-05T12:01:07Z") }
    { "_id" : ObjectId("5db21090d15e418f2d5b7b54"), "value" : 6, "date" : ISODate("2019-05-06T12:01:07Z") }
    { "_id" : ObjectId("5db21090d15e418f2d5b7b55"), "value" : 7, "date" : ISODate("2019-05-07T12:01:07Z") }
    

    我找到了解决方案,添加了minutes变量并使用它进行匹配。还将组数据更改为获取$last,而不是$first

    db.getCollection('weightedaverages').aggregate([
        {
          $match: {
            date: { $gte: ISODate('2019-05-26T15:00:00.000Z'), $lte: ISODate('2019-10-26T15:00:00.000Z') }
          }
        },
        {
          $project: {
            _id: 1,
            value: 1,
            docDate: '$date',
            day: {
              '$dayOfMonth': '$date'
            },
            month: {
              '$month': '$date'
            },
            year: {
              '$year': '$date'
            },
            minutes: {
              $add: [
                {
                  $multiply: [
                    {
                      '$hour': '$date'
                    },
                    60
                  ] 
                }, 
                {
                  '$minute': '$date'
                } 
              ]
            } 
          }
        },
        { $match: { 'minutes' : { $lte : ISODate('2019-10-26T13:20:00.000Z').getHours() * 60 + ISODate('2019-10-26T13:20:00.000Z').getMinutes()}}},
        {
          $project: {
            _id: 1,
            value: 1,
            docDate: 1,
            date: {
              '$concat': [
                {
                  $substr: ['$year', 0, 4]
                },
                '-',
                {
                  $substr: ['$month', 0, 2]
                },
                '-',
                {
                  $substr: ['$day', 0, 2]
                }
              ]
            }
          }
        },
        {
          $group: {
            _id: '$date',
            objId: {
              $last: '$_id'
            },
            value: {
              $last: '$value'
            },
            date: {
              $last: '$docDate'
            }
          }
        },
        {
          $project: {
            _id: '$objId',
            value: 1,
            date: 1
          }
        },
        {
          '$sort': {
            date: 1
          }
        }
      ]
    )
    
    输出:

    {
      "date" : ISODate("2019-08-20T15:00:13.633Z"),
      "value" : 10
    },
    {
      "date" : ISODate("2019-08-19T15:00:19.850Z"),
      "value" : 5
    },
    ...
    {
      "date" : ISODate("2019-06-20T14:59:48.000Z"),
      "value" : 7
    }
    

    有时人们会意外地将日期存储为字符串,而不是ISODate()。能否显示db.mycollection.find()的输出?(前几条记录就足够了,只需查看日期的数据类型即可)。它们存储在datetime中,我只是将它们作为字符串放在这里,以便您了解情况。这是我数据库中的一条记录:{“value”:5,“date”:ISODate(“2019-05-26T12:01:07.000Z”)}做得不错。我测试了这个,效果很好!好奇-什么是使用
    {$match:{'minutes':{$lte:15*60}}}
    ?我编辑了它,15是从初始时间范围开始的小时,然后乘以60将其转换为分钟,我还添加了现在编辑的分钟,以获得更准确的数据。