web-dev-qa-db-ja.com

MySQL match()against()-関連性と列による順序?

さて、私は複数の列で全文検索をしようとしていますが、これは次のような単純なものです:

SELECT * FROM pages WHERE MATCH(head, body) AGAINST('some words' IN BOOLEAN MODE)

今、私は関連性で注文したいです(単語がいくつ見つかりましたか?)これを次のようなことでできました:

SELECT * , MATCH (head, body) AGAINST ('some words' IN BOOLEAN MODE) AS relevance 
FROM pages
WHERE MATCH (head, body) AGAINST ('some words' IN BOOLEAN MODE)
ORDER BY relevance

さて、ここで私が迷子になる部分があります。head列の関連性に優先順位を付けたいと思います。

head用とbody用の2つの関連列を作成できると思いますが、その時点で、テーブルで同じ検索を3回行い、この関数を作成すると、クエリが結合され、他のテーブルと照合されるため、パフォーマンスが重要です。

だから、私の主な質問は、関連性を検索して特定の列に優先順位を付けるより速い方法はありますか? (そして、ボーナスとして、列に単語が出現する回数を関連性カウントとすることもできますか?)

どんな提案やアドバイスも素晴らしいでしょう。

注:これをLAMPサーバーで実行します。 (ローカルテストのWAMP)

72

このmightは、必要な頭部の関連性を高めます。 2倍になることはありませんが、おそらくあなたにとっては十分かもしれません。

SELECT pages.*,
       MATCH (head, body) AGAINST ('some words') AS relevance,
       MATCH (head) AGAINST ('some words') AS title_relevance
FROM pages
WHERE MATCH (head, body) AGAINST ('some words')
ORDER BY title_relevance DESC, relevance DESC

-- alternatively:
ORDER BY title_relevance + relevance DESC

DBエンジンを切り替える柔軟性がある場合、調査する必要がある代替手段は Postgres です。オペレーターの重みを設定し、ランキングをいじることができます。

146

必要な人のために追加するだけです。テーブルを変更することを忘れないでください!

ALTER TABLE table_name ADD FULLTEXT(column_name);
11
Camilla

私はそうしなかったが、それは

MATCH (head, head, body) AGAINST ('some words' IN BOOLEAN MODE)

Shouldは、頭で見つかった一致に二重の重みを付けます。


ドキュメントページ でこのコメントを読んでください。あなたにとって価値があると思います:

Patrick O'Loneが2002年12月9日6:51 amに投稿

IN BOOLEAN MODEはほとんどの場合、関連度1.0を返すことに注意してください。意味のある関連性を得るには、次のことを行う必要があります。

SELECT MATCH('Content') AGAINST ('keyword1 keyword2') as Relevance 
FROM table 
WHERE MATCH ('Content') AGAINST('+keyword1+keyword2' IN BOOLEAN MODE) 
HAVING Relevance > 0.2 
ORDER BY Relevance DESC 

BOOLEAN MODEを使用するWHERE句と組み合わせた関連性要因を取得するために、通常の関連性クエリを実行していることに注意してください。 BOOLEAN MODEは、BOOLEAN検索の要件を満たすサブセットを提供し、関連性クエリは関連性要素を満たし、HAVING句(この場合)は、ドキュメントが検索に関連することを保証します(つまり、スコアが0.2未満のドキュメント)無関係と見なされます)。これにより、関連性に基づいて注文することもできます。

これは、IN BOOLEAN MODEの動作のバグである場合とそうでない場合がありますが、メーリングリストで読んだコメントでは、IN BOOLEAN MODEの関連性ランキングはそれほど複雑ではないため、実際に関連文書を提供します。ところで-2つのMATCH句が異なっていても、MySQLはFULLTEXT検索を1回しか実行しないため、これを行うことによるパフォーマンスの低下に気付きませんでした。 EXPLAINを使用してこれを証明します。

したがって、「これを証明するためにEXPLAINを使用する」必要がありますが、全文検索を2回呼び出すことを心配する必要はないようです

9
jisaacstone

私もこれで遊んでいました。重みを追加する方法の1つは、コードのORDER BY領域です。

たとえば、3つの異なる列を一致させ、特定の列をより重くしたい場合:

SELECT search.*,
MATCH (name) AGAINST ('black' IN BOOLEAN MODE) AS name_match,
MATCH (keywords) AGAINST ('black' IN BOOLEAN MODE) AS keyword_match,
MATCH (description) AGAINST ('black' IN BOOLEAN MODE) AS description_match
FROM search
WHERE MATCH (name, keywords, description) AGAINST ('black' IN BOOLEAN MODE)
ORDER BY (name_match * 3  + keyword_match * 2  + description_match) DESC LIMIT 0,100;
3
Noah King