2013-03-08 5 views
20

Elasticsearchは「類似」のドキュメントを取得するには、2つの類似した機能を備えています。それは私に与えられたものに似た書類を与えます。私はより複雑な表現でそれを使用することはできません。Elasticsearch API「もっとこのように」対more_like_thisクエリ

また、があります。ブール式やブースティング式で使用できますが、ドキュメントのIDを与えることはできません。 "like_text"パラメータを指定する必要があります。

私にはタグと内容のドキュメントがあります。いくつかの文書は良いタグを持ち、あるものはタグを持たないものもあります。私は毎回動作する「類似ドキュメント」機能が必要ですが、一致するテキストを含むドキュメントよりも一致するタグを持つドキュメントをランク付けします。私の考えでした:"more_like_this"には"id"がないため

{ 
    "boosting" : { 
     "positive" : { 
      "more_like_this" : { 
       "fields" : ["tag"], 
       "id" : "23452", 
       "min_term_freq" : 1 
      } 
     }, 
     "negative" : { 
      "more_like_this" : { 
       "fields" : ["tag"], 
       "id" : "23452", 
      } 
     }, 
     "negative_boost" : 0.2 
    } 
} 

は明らかにこれは動作しません。代替案は何ですか?

答えて

41

まず、この機能のようなものとその動作について少し紹介します。アイデアはあなたが特定のドキュメントを持っていて、それに似ている他のドキュメントを持っていたいということです。

これを達成するには、現在のドキュメントからいくつかのコンテンツを抽出し、それを使用して類似するものを取得するクエリを作成する必要があります。 luceneに格納されているフィールド(またはluceneの格納されたフィールドであるelasticsearch_sourceフィールド)からコンテンツを抽出して、何らかの形でそれを再解析するか、用語ベクトルに格納された情報を使用してテキストを再分析することなく、照会に使用することができます。私はelasticsearchが単語ベクトルが利用可能である場合にこの後者のアプローチを試みるかどうかはわかりません。

more like this queryは、どこから取得したかに関係なく、テキストを入力できます。そのテキストは、選択したフィールドを照会して同様のドキュメントを取得するために使用されます。テキストは完全には使用されませんが、再分析され、min_doc_freqから少なくともmin_term_freq(最小期間頻度、デフォルト2)と文書頻度を持つ用語のうち、最大でmax_query_terms(デフォルト25)の値が保持されます。 max_doc_freq。生成されたクエリに影響を与える可能性のあるパラメータも多くあります。

more like this apiは、ドキュメントのIDとフィールドのリストを提供できるようにさらに進んでいます。これらのフィールドの内容は、その特定のドキュメントから抽出され、同じフィールドでこのようなクエリを作成するために使用されます。つまり、このクエリのように生成されたものは、以前に抽出されたテキストを含むプロパティテキストを持ち、同じフィールドで実行されます。ご覧のように、apiはこのようなクエリをボンネットの下で実行します。

このクエリは、他のクエリと組み合わせることができ、好きなソースからテキストを取得できるため、より柔軟になります。 一方、このapiのように、いくつかの制限がありますが、より多くの作業を行う共通の機能が公開されています。

あなたのケースでは、私は強力なelasticsearchクエリDSLを使用したり、クエリを別の方法で増やしたりするなど、このようなクエリを組み合わせることができます。欠点は、文書を抽出するために文書のIDを指定できないため、テキストを自分で入力する必要があることです。

あなたが望むものを達成するためのさまざまな方法があります。私はbool queryを使って、should節でこのような2つのクエリを組み合わせ、それらに異なる重みを与えます。また、一度に1つのフィールドを照会したいので、代わりにmore like this field queryを使用します。

{ 
    "bool" : { 
     "must" : { 
      {"match_all" : { }} 
     }, 
     "should" : [ 
      { 
       "more_like_this_field" : { 
       "tags" : { 
        "like_text" : "here go the tags extracted from the current document!", 
        "boost" : 2.0 
       } 
       } 
      }, 
      { 
       "more_like_this_field" : { 
       "content" : { 
        "like_text" : "here goes the content extracted from the current document!" 
       } 
       } 
      } 
     ], 
     "minimum_number_should_match" : 1 
    } 
} 

少なくとも1つのshould節が一致しなければならず、タグの一致がコンテンツの一致よりも重要です。

+0

感謝を。したがって、存在しないid "JSON名の唯一の選択肢は、フルテキストを取得してそれを' 'like_text" 'に置くことです。全文の往復を避ける方法はありません。それを減らす方法もありません。例えば。文書の用語ベクトルにアクセスし、25個の "トップ用語"しか得られないので、それらを '' like_text "'に直接置き、フルテキストと同じ結果を得ることができます。ご確認ください。私は、ドキュメントのトップn条件を与えるelasticsearchプラグインを書くことを考えていました。それがうまくいくと思いますか? –

+0

私が知る限り、あなたが望むものを達成するためのすぐれた方法はありません。おそらく、入力としてドキュメントのIDを受け取り、そこからテキストを取得するこのクエリのような新しいタイプを公開するプラグインを書くことができます。利用可能な場合は用語ベクトルを使用することもできます。 – javanna

8

これは新しいのような構文で可能になりました:

{ 
    "more_like_this" : { 
     "fields" : ["title", "description"], 
     "like" : [ 
     { 
      "_index" : "imdb", 
      "_type" : "movies", 
      "_id" : "1" 
     }, 
     { 
      "_index" : "imdb", 
      "_type" : "movies", 
      "_id" : "2" 
     }], 
     "min_term_freq" : 1, 
     "max_query_terms" : 12 
    } 
} 

はこちらをご覧ください:答えをhttps://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-mlt-query.html

+1

最近のElasticSearchのバージョンでは、 'docs'キーワードの代わりに' like'が使用されています。 – cosimo

+0

@cosimo答えを更新しました。ありがとう – Datageek

関連する問題