web-dev-qa-db-ja.com

Elasticsearch「MoreLikeThis」APIとmore_like_thisクエリ

Elasticsearchには、「類似した」ドキュメントを取得するための2つの類似した機能があります。

"More Like This API" があります。それは私に与えられたものに似た文書を与えてくれます。しかし、もっと複雑な表現では使用できません。

"more_like_this"クエリで検索APIで使用する ブール式またはブースティング式で使用できますが、ドキュメントのIDを指定できません。 "like_text"パラメーターを指定する必要があります。

タグとコンテンツを含むドキュメントがあります。一部のドキュメントには適切なタグがあり、一部にはタグがありません。毎回機能するが、一致するタグを持つドキュメントを一致するテキストを持つドキュメントよりも高くランク付けする「類似ドキュメント」機能が必要です。私の考えは:

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

"id""more_like_this"がないため、明らかにこれは機能しません。選択肢は何ですか?

22
Antoni Myłka

まず最初に、この機能のようなものとその仕組みについて少し紹介します。アイデアは、特定のドキュメントがあり、それに類似した他のドキュメントが必要な場合です。

これを実現するには、現在のドキュメントからいくつかのコンテンツを抽出し、それを使用してクエリを作成し、同様のコンテンツを取得する必要があります。 luceneの保存フィールド(またはelasticsearch _sourceフィールド。これは事実上luceneの保存フィールドです)からコンテンツを抽出し、何らかの方法で再分析するか、用語ベクトルに保存されている情報を使用して(インデックス作成中に有効になっている場合)、用語のリストを取得できます。テキストを再分析することなく、クエリに使用できます。ただし、用語ベクトルが利用可能な場合、elasticsearchがこの後者のアプローチを試みるかどうかはわかりません。

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

このAPIに似ています はさらに一歩進んで、ドキュメントのIDと、フィールドのリストを提供できるようにします。これらのフィールドのコンテンツは、その特定のドキュメントから抽出され、同じフィールドでこのクエリのようなものを作成するために使用されます。つまり、このクエリのように生成されたものには、以前に抽出されたテキストを含むプロパティテキストが含まれ、同じフィールドで実行されます。ご覧のとおり、このapiは、内部でこのクエリのように実行されます。

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

あなたの場合、このクエリのようないくつかの異なるクエリを組み合わせて、強力なElasticsearchクエリDSLを利用したり、クエリを異なる方法でブーストしたりできるようにします。欠点は、抽出するドキュメントのIDを指定できないため、テキストを自分で指定する必要があることです。

あなたが望むものを達成するためのさまざまな方法があります。 bool query を使用して、このクエリのように2つをshould句で結合し、異なる重みを付けます。一度に1つのフィールドをクエリするため、代わりに このフィールドクエリに似ています を使用します。

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

このように、should句の少なくとも1つが一致する必要があり、タグの一致はコンテンツの一致よりも重要です。

45
javanna

これは、新しいlike構文で可能になりました。

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

10
Datageek