web-dev-qa-db-ja.com

MYSQL全文検索結果を関連性でソートする方法

私はMYSQLに比較的慣れておらず、しばらくの間私を悩ませてきた問題がありました。私は答えを得るために至る所でグーグルを試みましたが、まだ許容できる解決策を見つけることができません。

特定の検索用語に最も一致するものを見つけるために現在実行しているクエリは次のとおりです。

$query="SELECT * from `vocabulary` WHERE translation = 'Word' OR translation LIKE '%Word%'";

返される結果は、関連するすべての行が含まれるという点で包括的です。ただし、特定の順序で並べ替えられているわけではないので、PHPで結果を出力するときに、完全に一致するものを最初に表示したいと思います。このような:


1 |単語<-完全一致
2 |クロスワード<-アルファベット順にソートされた部分一致/
3 |言葉
4 |ワードスミス


よろしくお願いします。

-macspacejunkie

24
user125591
SELECT * from vocabulary 
WHERE translation like 'Word'  
union all
SELECT * from vocabulary 
WHERE translation LIKE '%Word%' and translation not like 'Word'  

最初に完全一致が一覧表示されます

15
Rashmi Pandit

LIKEは 全文検索 ではありません。全文検索では、MATCH(...) AGAINST(...)は、関連性として大まかに概算できる一致スコアを返します。

29
instanceof me

全文インデックスを作成し、検索語と照合することで、関連性の高い検索を行うことができます。

したがって、このようなものが機能するはずです。

ALTER TABLE `vocabulary` ADD FULLTEXT INDEX `SEARCH`(`translation`);

SELECT *, MATCH(translation) AGAINST ('+Word' IN BOOLEAN MODE) AS relevance 
FROM `vocabulary`
WHERE MATCH(translation) AGAINST ('+Word' IN BOOLEAN MODE)
ORDER BY relevance DESC

詳細については、 MySQLリファレンスマニュアル を参照してください。

22
Rich Adams

私は同じ問題を検討してきましたが、私の状況に対する完全な答えはまだ見つかりませんでしたが、これはあなたにとって役立つかもしれません。私は全文検索にもかなり慣れていないので、専門家も私を助けてくれます。

Selectで2つのMATCH()AGAINST()ステートメントを実行し、それぞれのスコアを組み合わせて、全体的な関連性を形成します。異なる乗数を割り当てることで、結果の各セットの重要性を構成できます。

最初のMATCH()は、二重引用符を使用してリテラル(または正確な)検索語をチェックします。2番目のMATCHは通常どおりチェックします。最初の一致に高い乗数を適用するので、見つかった場合は関連性の値が高くなります。

このようなもの。

SELECT *, ((MATCH(indexes) AGAINST ('"search_terms"' IN BOOLEAN MODE) * 10)  
           + (MATCH(indexes) AGAINST ('search_terms' IN BOOLEAN MODE) * 1.5)) AS relevance  
FROM ...
WHERE ...  
      AND (MATCH (indexes) AGAINST ('"search_terms"' IN BOOLEAN MODE) > 0  
           OR MATCH (indexes) AGAINST ('search_terms' IN BOOLEAN MODE) > 0)  
      ...
ORDER BY relevance DESC

EXPLAIN関数を使用してクエリがどのように機能するかを示す場合、MySQLの機能により、追加のMATCH()AGAINST()句が実際にクエリにオーバーヘッドを追加しないことがわかります。

5
chrismacp

クエリを少し変更するだけで、探している順序を取得できます。

SELECT * 
FROM vocabulary
WHERE translation LIKE '%Word%'
ORDER BY translation <> 'Word', translation;

translationが正確に'Word'の場合、結果の一番上に表示されます。これは、前に完全一致がある場合、translation <> 'Word'がになるためです。 1は、他のすべての結果に対して返されます。その後、, translationのため、残りの結果はアルファベット順にソートされます。

このクエリは、選択した回答がUNIONで行うように2つのクエリを実行することを回避します。さらに、後半は常に実行され、最初の部分のスーパーセットであるため、クエリにはtranslation = 'Word' OR translation LIKE '%Word%'は必要ありません。

actual全文検索を使用する回答をお探しの場合は、他のより賛成の回答をご覧ください。

3
Phistrom