2017-11-23 6 views
2

私はElasticsearchにインデックスされた日次販売データをいくつか持っています。私は正常に私は今、次の操作を行うための単一のクエリを記述しようとしていますなどの日付の範囲を越えトップ売り手を識別するために期間Aと期間Bを識別するための弾性集計

を集計の数を実行します。

  • 日付範囲にわたりトップのn売り手を特定します(期間B)
  • 期間Aから期間Bまでの売上を比較し、X%を上回る割合が増加したものを特定します。

これまでの私の試み:初期フィルタは期間ごとに開始日を実行しているように、2つの期間のために、この出力結果が、

{ 
    "query": { 
    "bool": { 
     "filter": [ 
     { 
      "range": { 
      "date": { 
       "gte": "2017-10-01", 
       "lte": "2017-10-14" 
      } 
      } 
     } 
     ] 
    } 
    }, 
    "size": 0, 
    "aggs": { 
    "data_split": { 
     "terms": { 
     "size": 10, 
     "field": "product_id" 
     }, 
     "aggs": { 
     "date_periods": { 
      "date_range": { 
      "field": "date", 
      "format": "YYYY-MM-dd", 
      "ranges": [ 
       { 
       "from": "2017-10-01", 
       "to": "2017-10-07" 
       }, 
       { 
       "from": "2017-10-08", 
       "to": "2017-10-14" 
       } 
      ] 
      }, 
      "aggs": { 
      "product_id_split": { 
       "terms": { 
       "field": "product_id" 
       }, 
       "aggs": { 
       "unit_sum": { 
        "sum": { 
        "field": "units" 
        } 
       } 
       } 
      } 
      } 
     } 
     } 
    } 
    } 
} 

、私はこれは私が欲しいかなり何であるとは思いませんBの終了日と私は期間Aの代わりにその範囲の結果を合計すると思います。私も%比較を取得していない、私はおそらく私のアプリケーションレベルでこれを行うだろうが、私はスクリプトの弾性クエリで処理することができます理解していますか?

トップnの代わりに期間Aが表示される場合は、売上高のしきい値を1,000と設定すると特に効果的です。

いずれのポインタも大歓迎です。前もって感謝します!

は現在、弾性5.6

答えて

1
{ 
    "query": { 
    "bool": { 
     "filter": [ 
     { 
      "range": { 
      "date": { 
       "gte": "2017-10-01", 
       "lte": "2017-10-14" 
      } 
      } 
     } 
     ] 
    } 
    }, 
    "size": 0, 
    "aggs": { 
    "data_split": { 
     "terms": { 
     "size": 10, 
     "field": "product_id" 
     }, 
     "aggs": { 
     "date_period1": { 
      "filter": { 
      "range": { 
       "date": { 
       "gte": "2017-10-01", 
       "lte": "2017-10-07" 
       } 
      } 
      }, 
      "aggs": { 
      "unit_sum": { 
       "sum": { 
       "field": "units" 
       } 
      } 
      } 
     }, 
     "date_period2": { 
      "filter": { 
      "range": { 
       "date": { 
       "gte": "2017-10-08", 
       "lte": "2017-10-14" 
       } 
      } 
      }, 
      "aggs": { 
      "unit_sum": { 
       "sum": { 
       "field": "units" 
       } 
      } 
      } 
     }, 
     "percentage_increase": { 
      "bucket_script": { 
      "buckets_path": { 
       "firstPeriod": "date_period1>unit_sum", 
       "secondPeriod": "date_period2>unit_sum" 
      }, 
      "script": "(params.secondPeriod-params.firstPeriod)*100/params.firstPeriod" 
      } 
     }, 
     "retain_buckets": { 
      "bucket_selector": { 
      "buckets_path": { 
       "percentage": "percentage_increase" 
      }, 
      "script": "params.percentage > 5" 
      } 
     } 
     } 
    } 
    } 
} 

そしてこのgistにおける完全なテストデータを実行しています。この凝集の

結果はあなたにこれを与えている:

"aggregations": { 
    "data_split": { 
     "doc_count_error_upper_bound": 0, 
     "sum_other_doc_count": 0, 
     "buckets": [ 
     { 
      "key": "A", 
      "doc_count": 6, 
      "date_period1": { 
      "doc_count": 3, 
      "unit_sum": { 
       "value": 150 
      } 
      }, 
      "date_period2": { 
      "doc_count": 3, 
      "unit_sum": { 
       "value": 160 
      } 
      }, 
      "percentage_increase": { 
      "value": 6.666666666666667 
      } 
     }, 
     { 
      "key": "C", 
      "doc_count": 2, 
      "date_period1": { 
      "doc_count": 1, 
      "unit_sum": { 
       "value": 50 
      } 
      }, 
      "date_period2": { 
      "doc_count": 1, 
      "unit_sum": { 
       "value": 70 
      } 
      }, 
      "percentage_increase": { 
      "value": 40 
      } 
     } 
     ] 
    } 
    } 

アイデアは、あなたが2つの日付の間隔の集計の2つのfilterタイプを使用することです。そしてそれぞれのために合計を計算します。次に、タイプbucket_scriptの3番目の集計を使用すると、増加率が計算されます(ただし、たとえば売上の減少がマイナスになることに注意してください)。 次に、タイプbucket_selectorのさらに別の集約を使用して、パーセントが5%を超えるところでproduct_idを保持します。

+0

これは素晴らしいAndreiに見えます。私は今これを試してみます。 – Raoot

+0

それはあなたのために働いたのですか? –

+0

はい、本当にうまくいきます!ありがとうございました。 – Raoot

関連する問題