在一个查询中查找最近的日期

时间:2015-10-26 14:54:15

标签: mongodb mongoose

我目前正在试图找到一种方法,可以找到mongoDB中最近的条目日期,以便我正在寻找。

目前我通过使用2个查询解决了这个问题。一个使用$ gte和limit(1)来查找下一个更大的日期,然后使用$ lte - limit(1)来查看是否有更接近的日期可能更低。

我想知道,如果可能有办法在一个查询中找到最接近的日期,但无法找到任何关于此问题的任何内容。

希望你能帮助我,或者至少告诉我这是唯一的方法。

db.collection.find({"time":{$gte: isoDate}}).sort({"time":1}).limit(1)
db.collection.find({"time":{$lte: isoDate}}).sort({"time":-1}).limit(1)

但我正在寻找一种方法在一个查询中执行此操作,因此我不必减去结果以找到最接近的结果。

4 个答案:

答案 0 :(得分:3)

检查一下

db.collection.find({"time":{$gte: isoDate,$lt: isoDate}}).sort({"time":1}).limit(1)

请使用mongodb支持的相同格式,如followiong

ISODate("2015-10-26T00:00:00.000Z")

答案 1 :(得分:1)

我通过聚合解决了类似的问题。

样本数据:

{ 
  "_id" : ObjectId("5e365a1655c3f0bea76632a0"), 
  "time" : ISODate("2020-02-01T00:00:00Z"), 
  "description" : "record 1" 
}
{ 
  "_id" : ObjectId("5e365a1655c3f0bea76632a1"), 
  "time" : ISODate("2020-02-01T00:05:00Z"), 
  "description" : "record 2"
}
{
  "_id" : ObjectId("5e365a1655c3f0bea76632a2"), 
  "time" : ISODate("2020-02-01T00:10:00Z"), 
  "description" : "record 3"
}
{ 
  "_id" : ObjectId("5e365a1655c3f0bea76632a3"), 
  "time" : ISODate("2020-02-01T00:15:00Z"), 
  "description" : "record 4"
}
{ 
  "_id" : ObjectId("5e365a1655c3f0bea76632a4"), 
  "time" : ISODate("2020-02-01T00:20:00Z"), 
  "description" : "record 5"
}
{ 
  "_id" : ObjectId("5e365a1655c3f0bea76632a5"), 
  "time" : ISODate("2020-02-01T00:25:00Z"), 
  "description" : "record 6"
}

我正在寻找最接近ISODate('2020-02-01T00:18:00.000Z')的记录。

db.test_collection.aggregate([
{
    $match: 
        {
            time: 
                {
                    $gte: ISODate('2020-02-01T00:13:00.000Z'), 
                    $lte: ISODate('2020-02-01T00:23:00.000Z')
                }
        }
},
{
    $project:
        {
            time: 1,
            description: 1,
            time_dist: {$abs: [{$subtract: ["$time", ISODate('2020-02-01T00:18:00.000Z')]}]}}
},
{
    $sort: {time_dist: 1}
},
{
    $limit: 1
}])

$ match阶段设置一个“时间窗口”。在此示例中,我用了5分钟。

$ project阶段添加一个时间距离字段。这是每条记录从ISODate('2020-02-01T00:18:00.000Z')的查询时间开始的时间,以毫秒为单位。

然后我对time_dist字段进行排序,并将结果限制为1,以返回时间最接近ISODate('2020-02-01T00:18:00.000Z')的记录。

聚合结果:

{ 
  "_id" : ObjectId("5e365a1655c3f0bea76632a4"), 
  "time" : ISODate("2020-02-01T00:20:00Z"), 
  "description" : "record 5", 
  "time_dist" : NumberLong(120000)
}

答案 2 :(得分:0)

在 Pymongo 中,我使用了以下函数。这个想法是取一个 datetime 对象,从中减去一些天数并添加一些天数,然后在这两个日期之间找到一个日期。如果没有这样的记录,请增加日期跨度:

import datetime, dateutil

def date_query(table, date, variance=1):
  '''Run a date query using closest available date'''
  try:
    date_a = date - dateutil.relativedelta.relativedelta(days=variance)
    date_b = date + dateutil.relativedelta.relativedelta(days=variance)
    result = db[table].find({'date': {'$gte': date_a, '$lt': date_b}}).sort([('date', 1)])
    result = list(result)
    assert len(result) >= 1
    return result[len(result)//2] # return the result closest to the center
  except:
    return date_query(table, date, variance=variance*2)

答案 3 :(得分:0)

根据https://stackoverflow.com/a/33351918/4885936 不需要 ISODate 简单易行的解决方案是: 如果您希望离截止日期还剩 1 小时,只需简单地:

const tasks = await task.find({
      time: {
        $gt: Date.now(),
        $lt: Date.now() + 3600000 // one hour to miliseconds
      }
    })

此代码从现在到一小时后获取任务。