私は3つのレベルで親/子構造を持っています。まあ言ってみれば:
会社->従業員->可用性
ここでは可用性(および従業員も)が頻繁に更新されるため、ネストに対して親/子構造を使用することを選択します。そして、検索機能は正常に動作します(すべてのドキュメントが正しいシャードにあります)。
次に、これらの結果を並べ替えます。それらを会社(第1レベル)からのメタデータでソートするのは簡単です。ただし、3番目のレベル(可用性)でも並べ替える必要があります。
以下でソートされた会社のリストが必要です。
例えば:
会社Aは5マイルの距離にあり、評価4で最も早い従業員の1人が20時間以内に対応可能です。会社Bも5マイルの距離にあり、評価4ですが、従業員の1人が5時間以内に対応可能です。
したがって、ソート結果はB、Aである必要があります。
この各データに特別な重みを追加したいので、後でcustom_scoreスクリプトで使用できる集計を作成し始めました。
インデックスの作成、データのインポート、および検索の完全な要点
これで、実際に結果を返すクエリを作成できましたが、可用性の集計バケットが空です。ただし、構造化された結果も返されているので、それらを平坦化したいと思います。
現在私は戻ってきます:
会社IDS->従業員IDS->最初の可用性
次のような集計が必要です。
会社IDS->最初の可用性
このようにしてcustom_score
スクリプトでスコアを計算し、適切に並べ替えます。
より簡単な質問:
どのようにして、マルチレベル(大)の子供によってソート/集約し、結果を平坦化できるでしょう。
これを行うために集計は必要ありません。
これらはソート基準です:
#3を無視すると、次のような比較的単純なcompanyクエリを実行できます。
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は、最も近い各会社の可用性(company> employee> availability)に到達して見つける必要があるため、トリッキーですリクエストの時間。その期間をサードソート基準として使用します。
孫レベルでfunction_score
クエリを使用して、リクエスト時間とヒット_score
の各空き時間の時間差を取得します。 (次に、_score
を3番目のソート基準として使用します)。
孫に到達するには、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
(Availability)は1 / number-of-hours-until-available
になります(つまり、maximumを使用できます)従業員ごとに利用可能になるまでの相互時間、および会社ごとに利用可能な最大相互(ly?)従業員)。
まとめると、companyのクエリを続行しますが、company> employee> availabiltyを使用して_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" }
}
}