2017-02-02 21 views
1

function_scorescript_scoreを使用してスクリプトを作成しようとしています。 私は、rankingsフィールドがtype="nested"であるいくつかの文書を持っています。 フィールドのマッピングは次のとおりです。ElasticSearch Painlessスクリプト:ネストされたオブジェクトの配列を反復する方法

"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ループを使用する必要があります。

  1. forループ:の代わりを使用して:私はまた、次のオプションを試してみました

    "function_score": { 
    "script_score": { 
        "script": { 
         "lang": "painless", 
         "inline": 
           "sum = 0;" 
           "for (item in doc['rankings_cug']) {" 
            "sum = sum + doc['rankings_cug.rank1'].value;" 
           "}" 
         } 
        } 
    } 
    

    : これまでのところ、私はこのようなものを使用するが、(コンパイルエラーを投げて)動作していないようinfor (item:doc['rankings'])成功しません。

  2. forループinを用いるが、オブジェクトの特定の要素を反復処理しようとしている、すなわち、rank1for (item in doc['rankings.rank1'].values)、実際にコンパイルが、rank1の長さゼロの配列を見出すと思われます。

私は、_sourceという要素はJSONのようなオブジェクトを返すことができるということを読んだことがありますが、わかっている限り、検索クエリではサポートされていません。

どうすればいいのですか?

ありがとうございます。

答えて

5

残念ながら、一般的にはElasticSearchスクリプトは(無痛を含む)このように、ネストされたドキュメントにアクセスする機能をサポートしていません。おそらく、あなたがそのような方法でそれらを反復できるようにする必要がある場合、ランキングが複数値のフィールドに格納されるマッピングとは異なる構造を考えてみてください。最終的に、ネストされたデータは、ここで説明されている方法でスコアを得ることができるように、正規化されて親ドキュメントに入れられる必要があります。

+0

答えをありがとう。はい、私は実際に自分のデータを表現する方法を変えました。私は私の内部オブジェクトのキーとしてそれぞれ「件名」を使用してキーを使用して各オブジェクトにアクセスしました。 – christinabo

3

配列内のネストされたオブジェクトの場合、アイテムを反復処理して機能しました。

{ 
    "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 
       } 
      } 
    } 
} 

更新するスクリプト上で使用される:ここで

{ 
    "_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 
    } 
} 

ネストされたオブジェクトを反復処理するために "無痛" スクリプトです: elasticsearchインデックスに私のサンプルデータを以下に示します/ activity_index /ログ/ AVjx0UTvgHp45Y_tQP6z/_update スクリプトでは、2つの引数を含む 'contains'という関数を作成しました。関数を呼び出しました。 古いグルーヴィースタイル:ES 5.Xストアが別の文書内のオブジェクトを入れ子になったので、ctx._source.task_log.contains()は動作しません。これが役立つことを願っています! '

関連する問題