2016-08-15 6 views
1

私はelasticsearchを使用しています2.3Elasticsearch 2.x、タグのクエリ、およびタグweigthによる結果の並べ替え

私は書籍のインデックスを持っています。各本にはタグがあり、各タグには重みがあります。 私はタグの重みでソートされた、要求されたタグを持つすべての書籍を取得したい。例えば

PUT book/book/0 
{ 
    "name": "book 0", 
    "tags": [ 
     {"t": "comedy", "w": 30}, 
     {"t": "drama","w": 20}, 
    ] 
} 

PUT book/book/1 
{ 
    "name": "book 1", 
    "tags": [ 
     {"t": "comedy", "w": 10}, 
     {"t": "drama","w": 5}, 
     {"t": "other","w": 50}, 
    ] 
} 

PUT book/book/2 
    { 
     "name": "book 2", 
     "tags": [ 
      {"t": "comedy", "w": 5}, 
      {"t": "drama","w": 30}, 
     ] 
    } 

PUT book/book/3 
    { 
     "name": "book 3", 
     "tags": [ 
      {"t": "comedy", "w": 5}, 
      {"t": "other","w": 30}, 
     ] 
    } 

iは、タグのコメディとドラマを持っているすべての書籍を検索したいです。 結果順序は:

  1. ブック0(20 + 30)
  2. ブック2(30 + 5)
  3. ブック1(10 + 5)

UPDATE:欲しい 両方のタグに一致する書籍のみを返す(そして要求されたタグだけをソートする)。 「ドラマ」と「コメディ」を検索すると、両方のタグを持つ書籍(この場合は書籍0、本1、書籍2)のみが、リクエストされたタグの重みでソートされます。

どうすれば入手できますか?クエリの任意の例?

答えて

3

Ibrahim's answerは正しいです。

タグの重み付けを考慮したい場合は、tagsnestedというオブジェクトとして索引付けする必要があります。これは、twがすべてリストにまとめられ、プロセス内の関連付けが失われるためです(here)。

nestedクエリでラップされたfunction_scoreクエリを使用して、一致するタグの重みだけを合計することができます。 scriptingを有効にする必要があります。ここで

例です。

GET /book/_search 
{ 
    "query": { 
    "nested": { 
     "path": "tags", 
     "query": { 
     "function_score": { 
      "query": { 
      "bool": { 
       "filter": [ 
       { 
        "terms": { 
        "tags.t": [ 
         "comedy", 
         "drama" 
        ] 
        } 
       } 
       ] 
      } 
      }, 
      "functions": [ 
      { 
       "script_score": { 
       "script": "return doc['tags.w'].value" 
       } 
      } 
      ], 
      "boost_mode": "replace" 
     } 
     }, 
     "score_mode": "sum" 
    } 
    } 
} 


=== EDIT書籍のみがタグ(この例では、コメディとドラマ)の両方が一致する場合@Eyal Chのさんのコメント===

を次それぞれの検索用語が独自のnestedクエリを必要とするため、少し複雑になります。

はここに例を示します

GET /book/_search 
{ 
    "query": { 
    "bool": { 
     "must": 
     [ 
     { 
      "nested": { 
      "path": "tags", 
      "query": { 
       "function_score": { 
       "query": { 
        "term": { 
        "tags.t": { 
         "value": "comedy" 
        } 
        } 
       }, 
       "functions": [ 
        { 
        "script_score": { 
         "script": "return doc['tags.w'].value" 
        } 
        } 
       ], 
       "boost_mode": "replace" 
       } 
      } 
      } 
     }, 
     { 
      "nested": { 
      "path": "tags", 
      "query": { 
       "function_score": { 
       "query": { 
        "term": { 
        "tags.t": { 
         "value": "drama" 
        } 
        } 
       }, 
       "functions": [ 
        { 
        "script_score": { 
         "script": "return doc['tags.w'].value" 
        } 
        } 
       ], 
       "boost_mode": "replace" 
       } 
      } 
      } 
     } 
    ] 
    } 
    } 
} 
+0

おかげで@Christoph Wurm。私が今抱えている唯一の問題は、コメディやドラマがタグですべての本を返すということです。しかし、私はコメディとドラマのタグですべての本が必要です。手伝ってくれますか? –

+0

@YyalChええ、私は答えに入れました。 –

+0

ありがとうございます!あなたの更新された答えでは、私は "score_mode": "sum"は表示されません。どのようにスコアをサマライズするのですか?それはデフォルトですか?私は別のスコア(平均のような)でそれを得たい場合。ありがとう。 –

1

はこれを試してください:あなたは常にもあなたのクエリに一致していないタグのため、すべての重みを合計したい場合

POST book/book/_search 
{ 
    "query": { 
     "match": { 
      "tags.t": "comedy drama" 
     } 
    }, 
    "sort": [ 
     { 
      "tags.w": { 
      "order": "desc", 
      "mode": "sum" 
      } 
     } 
    ] 
} 
+0

これは、すべてのタグの「W」でソートされます。私は要求されたタグ(コメディーのw +ドラマのw)の順番でのみそれをソートしたい –

関連する問題