_script_score
_の_function_score
_を使用してスクリプトを作成しようとしています。 rankings
フィールドが_type="nested"
_であるドキュメントがいくつかあります。フィールドのマッピングは次のとおりです。
_"rankings": {
"type": "nested",
"properties": {
"rank1": {
"type": "long"
},
"rank2": {
"type": "float"
},
"subject": {
"type": "text"
}
}
}
_
サンプル文書は次のとおりです。
_"rankings": [
{
"rank1": 1051,
"rank2": 78.5,
"subject": "s1"
},
{
"rank1": 45,
"rank2": 34.7,
"subject": "s2"
}]
_
私が達成したいのは、ランキングのネストされたオブジェクトを反復処理することです。実際、特定のsubject
を見つけて_rank1, rank2
_を使用して何かを計算するには、forループを使用する必要があります。これまでのところ、私はこのようなものを使用していますが、動作していないようです(コンパイルエラーをスロー):
_"function_score": {
"script_score": {
"script": {
"lang": "painless",
"inline":
"sum = 0;"
"for (item in doc['rankings_cug']) {"
"sum = sum + doc['rankings_cug.rank1'].value;"
"}"
}
}
}
_
また、次のオプションを試しました。
for
の代わりに_:
_を使用するin
ループ:for (item:doc['rankings'])
は成功しません。for
はin
を使用してループしますが、オブジェクトの特定の要素、つまり_rank1
_:for (item in doc['rankings.rank1'].values)
を反復処理しようとしますが、実際にはコンパイルされますが、 _rank1
_の長さゼロの配列を見つけます。__source
_要素はJSONに似たオブジェクトを返すことができる要素であると読みましたが、検索クエリではサポートされていないことがわかりました。
それを進める方法のアイデアを教えてください。
どうもありがとう。
params._source
経由で_sourceにアクセスできます。これは動作します:
PUT /rankings/result/1?refresh
{
"rankings": [
{
"rank1": 1051,
"rank2": 78.5,
"subject": "s1"
},
{
"rank1": 45,
"rank2": 34.7,
"subject": "s2"
}
]
}
POST rankings/_search
POST rankings/_search
{
"query": {
"match": {
"_id": "1"
}
},
"script_fields": {
"script_score": {
"script": {
"lang": "painless",
"inline": "double sum = 0.0; for (item in params._source.rankings) { sum += item.rank2; } return sum;"
}
}
}
}
DELETE rankings
残念ながら、ElasticSearchスクリプティングは一般に、この方法でネストされたドキュメントにアクセスする機能をサポートしていません(ペインレスを含む)。おそらく、ランキングを複数値のフィールドに格納するマッピングとは異なる構造を考えてください。このような方法でランキングを反復処理する必要がある場合です。最終的に、ネストされたデータは、ここで説明する方法でスコアを取得できるように、非正規化して親ドキュメントに入れる必要があります。
配列内のネストされたオブジェクトの場合、アイテムを繰り返し処理しました。次に、elasticsearchインデックスのサンプルデータを示します。
{
"_index": "activity_index",
"_type": "log",
"_id": "AVjx0UTvgHp45Y_tQP6z",
"_version": 4,
"found": true,
"_source": {
"updated": "2016-12-11T22:56:13.548641",
"task_log": [
{
"week_end_date": "2016-12-11",
"log_hours": 16,
"week_start_date": "2016-12-05"
},
{
"week_start_date": "2016-03-21",
"log_hours": 0,
"week_end_date": "2016-03-27"
},
{
"week_start_date": "2016-04-24",
"log_hours": 0,
"week_end_date": "2016-04-30"
}
],
"created": "2016-12-11T22:56:13.548635",
"userid": 895,
"misc": {
},
"current": false,
"taskid": 1023829
}
}
ネストされたオブジェクトを反復処理する「痛みのない」スクリプトを次に示します。
{
"script": {
"lang": "painless",
"inline":
"boolean contains(def x, def y) {
for (item in x) {
if (item['week_start_date'] == y){
return true
}
}
return false
}
if(!contains(ctx._source.task_log, params.start_time_param) {
ctx._source.task_log.add(params.week_object)
}",
"params": {
"start_time_param": "2016-04-24",
"week_object": {
"week_start_date": "2016-04-24",
"week_end_date": "2016-04-30",
"log_hours": 0
}
}
}
}
上記の更新用スクリプトを使用:/ activity_index/log/AVjx0UTvgHp45Y_tQP6z/_updateスクリプトで、2つの引数を持つ「含む」という関数を作成しました。関数を呼び出しました。古いgroovyスタイル:ctx._source.task_log.contains()は、ES 5.Xがネストされたオブジェクトを別のドキュメントに保存するため、機能しません。これがお役に立てば幸いです!