2016-09-29 16 views
0

私のインデックスには、各ドキュメントが(datetimeフィールドを使用して)yyyy-MM-dd'T'HH:mm:ssという形式でタイムスタンプされたドキュメントがありますElasticsearch:日付ヒストグラムの各バケットにフィルタ範囲を追加する

私はドキュメント内の特定のフィールドのバケツに毎日(日付ヒストグラム)の平均値を提供するクエリを持っています。これは問題なく動作します。

毎日の平均では、毎日の特定の部分のタイムスタンプのみが考慮されるように、各バケットをフィルタリングするように拡張しようとしています(午前または午後などに作成されたドキュメントのみ)。

私は次のクエリ試してみた:

{ 
    "size": 0, 
    "aggs": { 
     "rating": { 
     "date_histogram": { 
      "field": "datetime", 
      "interval": "1d", 
      "time_zone": "Europe/London", 
      "min_doc_count": 1 
     }, 
     "aggs": { 
      "afternoon": { 
       "filter": { 
        "range": { 
        "datetime": { 
         "gte": "12:00:00", 
         "lte": "17:00:00", 
         "format": "HH:mm:ss" 
        } 
        } 
       }, 
       "aggs": { 
        "service": { 
        "avg": { 
         "field": "qr2" 
        } 
        } 
       } 
      } 
     } 
     } 
    }, 
    "query": { 
     "constant_score": { 
     "filter": { 
      "range": { 
       "datetime": { 
        "gte": "2016-08-28T23:00:00", 
        "lte": "2016-09-29T07:34:49" 
       } 
      } 
     } 
     } 
    } 
} 

をしかし、これは親バケットは、時間帯に落ちるタイムスタンプを持つ複数の文書を持っているにもかかわらずアグリゲーション(0 DOC数)にnull値を返す - 参照します以下の例:

"aggregations": { 
     "rating": { 
     "buckets": [ 
      { 
       "key_as_string": "1472428800000", 
       "key": 1472425200000, 
       "doc_count": 843, 
       "afternoon": { 
        "doc_count": 0, 
        "service": { 
        "value": null 
        } 
       } 
      }, 
      { 
       "key_as_string": "1472515200000", 
       "key": 1472511600000, 
       "doc_count": 748, 
       "afternoon": { 
        "doc_count": 0, 
        "service": { 
        "value": null 
        } 
       } 
      }, 

私はちょうど日時の一部が所望の効果を持っていない、それはおそらく、したがって任意のタイムスタンプと一致しない、いくつかの値にデフォルト設定日付部分に範囲クエリをやっている時間を指定していることを推測していますthで返されたドキュメントの場合親バケット。

これを行う簡単な方法はありますか、タイムアウトを別のフィールドに分割する必要はありますか?

ご迷惑をおかけして申し訳ありません。

答えて

1

ご確認してください。しかし、2.1.0より前のバージョンでは、これはうまくいくようです。

{ 
    "script": { 
     "script": "def hod = doc.datetime.date.getHourOfDay(); return hod >= min && hod <= max", 
     "params": { 
      "min": 12, 
      "max": 17 
     } 
    } 
} 

これは古いバージョンの問題が修正されたためです。 https://github.com/elastic/elasticsearch-net/issues/1931

3

これには2つの方法があります。

最初の解決策は、hourOfTheDayという別のフィールドにインデックスを付けて、簡単な数値のrangeフィルタを実行できるようにすることです。

  "filter": { 
       "range": { 
       "hourOfTheDay": { 
        "gte": 12, 
        "lte": 17 
       } 
       } 
      }, 

第二の溶液は、単にこの第二の解決のために

  "filter": { 
       "script": { 
       "script": { 
        "inline": "def hod = doc.datetime.date.getHourOfDay(); return hod >= min && hod <= max", 
        "params": { 
         "min": 12, 
         "max": 17 
        } 
       } 
       } 
      }, 

scriptフィルタでのGroovyスクリプトを使用することを含む、上記の答えは完璧に動作enable dynamic scripting

+0

ありがとうございました。私は動的スクリプトを有効にしたくないので、私は時間フィールドを追加する必要があるように見えます。 – InTooDeep

+0

クール、それは助けてうれしい! – Val

関連する問題