26

MySQL の FULLTEXT インデックスを使用して、PHP Web アプリの検索サポートを追加しようとしています。

テスト テーブルを作成し (MyISAM タイプを使用し、単一のテキスト フィールドを使用a)、いくつかのサンプル データを入力しました。私が正しければ、次のクエリはこれらの両方の行を返すはずです。

SELECT * FROM test WHERE MATCH(a) AGAINST('databases')

ただし、何も返しません。私は少し調査を行い、私が知る限りすべてを正しく行っています.テーブルはMyISAMテーブルで、FULLTEXTインデックスが設定されています. プロンプトとphpMyAdminからクエリを実行しようとしましたが、うまくいきませんでした。私は何か重要なものを見逃していますか?


更新: OK、Cody のソリューションは私のテスト ケースでは機能しましたが、実際のテーブルでは機能しないようです。

CREATE TABLE IF NOT EXISTS `uploads` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` text NOT NULL,
  `size` int(11) NOT NULL,
  `type` text NOT NULL,
  `alias` text NOT NULL,
  `md5sum` text NOT NULL,
  `uploaded` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;

そして私が使用しているデータ:

INSERT INTO `uploads` (`id`, `name`, `size`, `type`, `alias`, `md5sum`, `uploaded`) VALUES
(1, '04 Sickman.mp3', 5261182, 'audio/mp3', '1', 'df2eb6a360fbfa8e0c9893aadc2289de', '2009-07-14 16:08:02'),
(2, '07 Dirt.mp3', 5056435, 'audio/mp3', '2', 'edcb873a75c94b5d0368681e4bd9ca41', '2009-07-14 16:08:08'),
(3, 'header_bg2.png', 16765, 'image/png', '3', '5bc5cb5c45c7fa329dc881a8476a2af6', '2009-07-14 16:08:30'),
(4, 'page_top_right2.png', 5299, 'image/png', '4', '53ea39f826b7c7aeba11060c0d8f4e81', '2009-07-14 16:08:37'),
(5, 'todo.txt', 392, 'text/plain', '5', '7ee46db77d1b98b145c9a95444d8dc67', '2009-07-14 16:08:46');

私が現在実行しているクエリは次のとおりです。

SELECT * FROM `uploads` WHERE MATCH(name) AGAINST ('header' IN BOOLEAN MODE)

行 3、header_bg2.png を返す必要があります。代わりに、別の空の結果セットを取得します。ブール検索の私のオプションは次のとおりです。

mysql> show variables like 'ft_%';
+--------------------------+----------------+
| Variable_name            | Value          |
+--------------------------+----------------+
| ft_boolean_syntax        | + -><()~*:""&| |
| ft_max_word_len          | 84             |
| ft_min_word_len          | 4              |
| ft_query_expansion_limit | 20             |
| ft_stopword_file         | (built-in)     |
+--------------------------+----------------+
5 rows in set (0.02 sec)

「header」は単語の長さの制限内にあり、それがストップ ワードであるとは思えません (リストの取得方法がわかりません)。何か案は?

4

2 に答える 2

50

さらにデータを追加します。デフォルトでは、MySQLは、テーブルの行の50%以上にある単語を無視します。これは、それが「ノイズ」単語であると見なすためです。

テーブル内の行が非常に少ない場合、この50%の制限に頻繁に達するのが一般的です(つまり、2つの行がある場合、すべての単語が行の少なくとも50%に含まれます!)。

于 2009-07-14T14:29:40.700 に答える
25

MySQL フルテキスト検索には、自然言語モードとブール モードの 2 つのモードがあります。自然言語モードの制限は、「 ... 行の 50% 以上に存在する単語は一般的であると見なされ、一致しません。修飾子が指定されていない場合、全文検索は自然言語検索です。」自然言語がデフォルトのモードです。これは、全文ドキュメントに記載されています。

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

クエリをブール モードの使用に切り替えると、次のようになります。

SELECT * FROM test WHERE MATCH(a) AGAINST('databases' IN BOOLEAN MODE)

次に、2 つの行が返されます。

ブール モードには独自の制限があります。一般的な制限の 1 つは、関連性の高い順に行を返さないことです。全体として、自然言語モードよりも多くの機能と柔軟性を提供するため、最終的には自然言語モードを使用することになるでしょう。

アプリケーションが全文検索に大きく依存する場合は、Lucene/SolrSphinxなどのよりフル機能のパッケージを検討することをお勧めします。

于 2009-07-14T14:28:11.013 に答える