1

ドキュメントサーバー側で2つの日付の差を計算し、クエリを実行することはできますか?(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)
]

サーバーサイドのJSとについて読んだことがありますeval()が、ドキュメントにはこれらは推奨されていないと書かれています-それらは最良のオプションですか?


(明らかに時間差を秒単位で追加フィールド("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
4

1 に答える 1

3

Sammayeが示唆しているように、それを行う唯一の方法は、aggregate()関数を使用することだと思います。たとえば、次のようなことを行います。

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

基本的に、既存のデータから計算される新しいランタイムフィールド「timediff」を定義しています。$match次に、パイプラインにステップを追加して、違いをフィルタリングできるようになります。

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

私はこの特定の例を試したことがないので、中かっこや角かっこがいくつか欠落している可能性があります...しかし、うまくいけば、あなたはその考えを理解するでしょう。集約フレームワークは、定義できるデータパイプラインの点で非常に強力です。

幸運を!

于 2012-12-28T21:13:47.303 に答える