15

mysql データベースの検索でハイフンが重要な「some-or-other」のようなキーワードがあります。私は現在全文機能を使用しています。

ハイフン文字をエスケープする方法はありますか? myisam/ftdefs.h#define HYPHEN_IS_DELIMファイルでコメント アウトする方法があることは知っていますが、残念ながら私のホストではこれが許可されていません。そこに別のオプションはありますか?

編集 3-8-11 ここに私が今持っているコードがあります:

$search_input = $_GET['search_input'];
$keyword_safe = mysql_real_escape_string($search_input);
$keyword_safe_fix = "*'\"" . $keyword_safe . "\"'*";


$sql = "
    SELECT *,
        MATCH(coln1, coln2, coln3) AGAINST('$keyword_safe_fix') AS score
        FROM table_name
    WHERE MATCH(coln1, coln2, coln3) AGAINST('$keyword_safe_fix')
    ORDER BY score DESC
";
4

4 に答える 4

18

ここからhttp://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

ダッシュまたはハイフンを含む単語を検索する1つの解決策は、ブールモードで全文検索を使用し、単語をハイフン/ダッシュで二重引用符で囲むことです。

またはここからhttp://bugs.mysql.com/bug.php?id=2095

別の回避策があります。最近マニュアルに追加されました:「文字セットファイルの変更:これは再コンパイルの必要はありません。true_word_char()マクロは「文字タイプ」テーブルを使用して文字と数字を他の文字と区別します。.次のいずれかの内容を編集できます。 '-'が「文字」であることを指定する文字セットXMLファイル。次に、指定された文字セットをFULLTEXTインデックスに使用します。 "

自分で試したことはありません。

編集:ここからいくつかの追加情報がありますhttp://dev.mysql.com/doc/refman/5.0/en/fulltext-boolean.html

二重引用符( "" ")文字で囲まれたフレーズは、入力されたとおりに、そのフレーズを文字通り含む行にのみ一致します。フルテキストエンジンは、フレーズを単語に分割し、フルテキストインデックスで単語の検索を実行します。 MySQL 5.0.3より前では、エンジンは見つかったレコード内のフレーズのサブストリング検索を実行したため、一致にはフレーズ内の非単語文字が含まれている必要があります。MySQL5.0.3以降、非単語文字は正確に一致する必要はありません。フレーズ検索では、一致にフレーズとまったく同じ単語が同じ順序で含まれている必要があります。たとえば、「testphrase」はMySQL 5.0.3の「test、phrase」と一致しますが、以前は一致しません。

フレーズにインデックスに含まれる単語が含まれていない場合、結果は空になります。たとえば、すべての単語がストップワードであるか、インデックス付き単語の最小長より短い場合、結果は空になります。

于 2011-03-04T10:54:49.610 に答える
5

次のクエリを使用することを提案する人もいます。

SELECT id 
FROM texts
WHERE MATCH(text) AGAINST('well-known' IN BOOLEAN MODE)
HAVING text LIKE '%well-known%';

しかし、それによって、使用される全文演算子に応じて多くのバリアントが必要になります。タスク: のようなクエリを実現します+well-known +(>35-hour <39-hour) working week*。複雑すぎる!

また、デフォルトの len を忘れないでください。ft_min_word_lenそのため、 を検索すると、結果でup-to-dateのみ返さdateれます。

騙す

そのため、私はトリックを好むため、HAVINGetc を使用した構成はまったく必要ありません。

  1. 次のテキストをデータベース テーブルに追加する代わりに:

    「The Up-to-Date Sorcerer」は、有名な SF 短編小説です。
    ハイフンなしのハイフン単語をコメント内のテキストの最後にコピーします。
    「The Up-to-Date Sorcerer」は、有名な SF 短編小説です。<!-- UptoDate wellknown -->

  2. ユーザーがup-to-dateSQL クエリでハイフンを削除して検索する場合:
    MATCH(text) AGAINST('uptodate ' IN BOOLEAN MODE)

up-to-dateこれにより、ユーザーは、のみを含むすべての結果を取得するのではなく、1 つの単語として見つけることができますdate( ft_min_word_lenkillupと のためto)。

もちろんecho、テキストの前に<!-- ... -->コメントを削除する必要があります。

利点

  • クエリはより簡単です
  • ユーザーは通常どおりすべての全文演算子を使用できます
  • クエリは高速です。
  • ユーザーが MySQL を検索すると-well-known +science、それを として扱いますnot include *well*, could include *known* and must include *science*。これは、ユーザーが期待したものではありません。トリックもそれを解決します(SQLクエリが検索するため-wellknown +science
于 2017-01-29T20:53:01.557 に答える
3

Binary演算子を使用する方が簡単かもしれません。

SELECT * 
FROM your_table_name 
WHERE BINARY your_column = BINARY "Foo-Bar%AFK+LOL"

http://dev.mysql.com/doc/refman/5.0/en/cast-functions.html#operator_binary

演算子は、それBINARYに続く文字列をバイナリ文字列にキャストします。これは、列の比較を文字単位ではなくバイト単位で行う簡単な方法です。BINARYこれにより、列がまたはとして定義されていない場合でも、比較で大文字と小文字が区別されBLOBます。BINARYまた、末尾のスペースが重要になります。

于 2012-01-29T04:32:04.337 に答える
0

これに対する私の推奨する解決策は、検索語と検索対象のデータからハイフンを削除することです。フルテキスト テーブルに と の 2 つの列を保持していsearchますreturnsearchさまざまな文字が削除されたサニタイズされたデータが含まれており、コードがそれらもサニタイズした後、ユーザーの検索用語と比較されます。

次に、return列を表示します。

これは、データベースにデータのコピーが 2 つあることを意味しますが、私にとっては、そのトレードオフには十分な価値があります。私の FT テーブルは 50 万行しかないので、私のユースケースでは大したことではありません。

于 2019-06-18T17:27:22.220 に答える