ElasticSearch の複数レベルの親子集約 質問する

ElasticSearch の複数レベルの親子集約 質問する

3 レベルの親/子構造があるとします。次のようにします。

会社 -> 従業員 -> 空き状況

ここでは可用性 (および従業員) が頻繁に更新されるため、ネストではなく親/子構造を使用することを選択します。また、検索機能は正常に動作します (すべてのドキュメントが正しいシャード内にあります)。

次に、これらの結果を並べ替えます。会社 (第 1 レベル) のメタデータで並べ替えるのは簡単です。ただし、第 3 レベル (可用性) でも並べ替える必要があります。

以下の基準で並べ替えられた企業のリストが欲しい:

  • ASC で指定された場所からの距離
  • 評価DESC
  • 最も早く利用可能 ASC

例えば:

会社 A は 5 マイル離れており、評価は 4 で、従業員の 1 人が対応可能になるのは最短で 20 時間後です。会社 B も 5 マイル離れており、評価は 4 ですが、従業員の 1 人が対応可能になるのは最短で 5 時間後です。

したがって、ソート結果は B、A である必要があります。

各データに特別な重みを追加したいので、後で custom_score スクリプトで使用できる集計を書き始めました。

インデックスの作成、データのインポート、検索の完全な概要

現在、実際に結果を返すクエリを作成できましたが、可用性集約バケットは空です。ただし、返される結果が構造化されすぎているため、フラット化したいと考えています。

現在、返されるもの:

企業ID -> 従業員ID -> 最初の利用可能

次のような集計をしたいと思います:

企業ID -> 最初の利用可能

この方法では、スクリプトを実行してスコアを計算し、適切に並べ替えることができますcustom_score

より単純な質問:
複数レベルの (孫) 子で並べ替え/集計し、結果をフラット化するにはどうすればよいでしょうか。

ベストアンサー1

これを行うには集計は必要ありません。

並べ替えの基準は次のとおりです。

  1. 距離 ASC (会社.所在地)
  2. 評価 DESC (company.rating_value)
  3. 最も早い将来の可用性 ASC (company.employee.availability.start)

3を無視すれば、比較的単純な会社次のようなクエリを実行します。

GET /companies/company/_search
{
 "query": { "match_all" : {} },
 "sort": {
    "_script": {
        "params": {
            "lat": 51.5186,
            "lon": -0.1347
        },
        "lang": "groovy",
        "type": "number",
        "order": "asc",
        "script": "doc['location'].distanceInMiles(lat,lon)"
    },
    "rating_value": { "order": "desc" }
  }
}

#3手を伸ばして空き状況を見つける必要があるため、難しいです(会社 > 従業員 > 空き状況)を各企業ごとにリクエストの時間に最も近い期間に設定し、その期間を三番目並べ替え基準。

孫レベルでクエリを使用してfunction_score、リクエスト時間とヒット内の各可用性の間の時間差を取得します。(次に、 を3 番目の並べ替え基準として_score使用します)。_score

孫に到達するには、クエリhas_child内でクエリを使用する必要がありますhas_child

各企業について、最も早く利用可能な従業員(そしてもちろん最も近い空き時間)が必要です。Elasticsearch 2.0は"score_mode": "min"このような場合に を提供しますが、今のところは に制限されているため、"score_mode": "max"_scoreを にします。相互時間差の。

          "function_score": {
            "filter": { 
              "range": { 
                "start": {
                  "gt": "2014-12-22T10:34:18+01:00"
                } 
              }
            },
            "functions": [
              {
                "script_score": {
                  "lang": "groovy",
                  "params": {
                      "requested": "2014-12-22T10:34:18+01:00",
                      "millisPerHour": 3600000
                   },
                  "script": "1 / ((doc['availability.start'].value - new DateTime(requested).getMillis()) / millisPerHour)"
                }
              }
            ]
          }

それで、_scoreそれぞれの孫(可用性)は1 / number-of-hours-until-available最大逆数従業員1人あたりの利用可能までの時間、および最大の逆数(?)利用可能な従業員数(会社あたり)

これらすべてをまとめると、私たちは引き続き質問します会社しかし、使用会社 > 従業員 > 空き状況を生成する_scoreために使用する#3並べ替え基準:

GET /companies/company/_search
{
 "query": { 
    "has_child" : {
        "type" : "employee",
        "score_mode" : "max",
        "query": {
          "has_child" : {
            "type" : "availability",
            "score_mode" : "max",
            "query": {
              "function_score": {
                "filter": { 
                  "range": { 
                    "start": {
                      "gt": "2014-12-22T10:34:18+01:00"
                    } 
                  }
                },
                "functions": [
                  {
                    "script_score": {
                      "lang": "groovy",
                      "params": {
                          "requested": "2014-12-22T10:34:18+01:00",
                          "millisPerHour": 3600000
                       },
                      "script": "1/((doc['availability.start'].value - new DateTime(requested).getMillis()) / millisPerHour)"
                    }
                  }
                ]
              }
            }
          }
        }
    }
 },
 "sort": {
  "_script": {
    "params": {
        "lat": 51.5186,
        "lon": -0.1347
    },
    "lang": "groovy",
    "type": "number",
    "order": "asc",
    "script": "doc['location'].distanceInMiles(lat,lon)"
  },
  "rating_value": { "order": "desc" },
  "_score": { "order": "asc" }
 }
}

おすすめ記事