【问题标题】:Difference between ISODates in each document?每个文档中 ISODates 之间的区别?
【发布时间】:2012-12-13 20:01:24
【问题描述】:

是否可以计算文档服务器端中两个日期之间的差异,并对其进行查询? (就像 SQL 的 DATEDIFF 函数)

假设我有很多这样的文件:

>>> db.collection.find()
[
    { "id" : ObjectId("1"), 
      "starttime" : ISODate("2011-12-01T05:01:00"), # 5:01 AM
      "endtime" : ISODate("2011-12-01T05:02:00")    # 5:02 AM 
    }, 

    { "id" : ObjectId("2"), 
      "starttime" : ISODate("2011-12-01T06:01:00"), # 6:01:00 AM
      "endtime" : ISODate("2011-12-01T06:01:30")    # 6:01:30 AM 
    }
]

有没有办法实现类似的东西?

只返回时差:

>>> db.collection.date_difference_seconds(endtime, starttime)
[60, 30]

或查询:

>>> db.collection.find("timediff(endtime-starttime) < 40 seconds")
[
    { "id" : ObjectId("2"), ...} # Just second document (30s diff)
]

我已经阅读了有关 server-side JSeval() 的信息,但文档说不推荐这些 - 它们是最佳选择吗?


(我显然可以将时间差以秒为单位添加为附加字段 ("time_diff": 30),或者在 Python 客户端计算差异,但我想知道它是否可能在服务器端)

客户端计算:

>>> for doc in (collection.find(None, {'starttime': 1, 'endtime': 1 }))
        doc['endtime']-doc['startime']
0:01:00.000000
0:00:30.000000

【问题讨论】:

  • 我想这样做你必须知道你想查询的时差?那么为什么不直接按不同的日期查询并计算客户端的差异呢?
  • @Sammaye 我不确定我是否跟随。我只对日期之间的差异感兴趣,而不是日期本身。你的意思是像我在问题中添加的 sn-p 吗?
  • 我不认为有一种特殊的方法可以在服务器端完成,但可以在一个语句客户端完成。例如:map(lambda x: (x['endtime'] - x['starttime']).total_seconds(), db.collection.find())
  • 好吧,其实我明白你想做什么:db.collection.find("timediff(endtime-starttime) &lt; 40 seconds") 我认为它更简单,但我没有考虑足够。嗯,有可能在这里使用$where 添加时间计算功能,这将避免 eval 但它会严重降低速度。我认为,如果您要使用聚合函数使用 docs.mongodb.org/manual/reference/aggregation/#date-operators 创建一个新的计算字段
  • MongoDB 没有等价物。因此,如果它是一个频繁查询,只需按照您的建议预先计算它并存储在一个附加字段中。您可以通过这种方式添加索引和排序等(如果需要)。或者可能是 MapReduce 函数,但该字段会更简单。

标签: python mongodb datetime pymongo timedelta


【解决方案1】:

正如 Sammaye 所建议的,我认为唯一的方法是使用 aggregate() 函数。例如,执行以下操作:

db.collection.aggregate([{$project: {timediff: {$subtract: ['$endtime' , '$starttime']}}}])

您实际上是在定义一个新的运行时字段“timediff”,它是根据现有数据计算得出的。然后,您应该能够将$match 步骤添加到管道以过滤差异:

db.collection.aggregate([{$project: {timediff: {$subtract: ['$endtime' , '$starttime']}}}, {$match: {timediff: {$lte: 40}}}])

我还没有尝试过这个具体的例子,所以可能会缺少一些大括号或括号......但希望你能明白这一点。就您可以定义的数据管道而言,聚合框架非常强大。

祝你好运!

【讨论】:

  • 只是对它的评论。 $lte : 40 不是 40 秒,至少我现在使用的当前 mongodb 版本返回毫秒。所以它应该是 $lte : 40000 以获得 40 秒的差异
猜你喜欢
  • 2021-02-20
  • 2013-05-20
  • 2022-11-06
  • 1970-01-01
  • 2019-10-21
  • 1970-01-01
  • 2012-03-24
  • 1970-01-01
  • 2020-07-08
相关资源
最近更新 更多