4

MySQL の単語のバリエーションを一致させるにはどうすればよいですか。たとえば、accountancy の検索は accountant、accountants、accounting などと一致する必要があります。共有ホスティングを使用しているため、levenshtein などの関数を MySQL に追加できません。

Google が 'accountant course' を検索したときに' accounting course ' と ' accountancy course ' を一致させる方法に似たものが必要です。

私のサーバー言語は php です。SQL ではなく、そこに実装できる場合のみです。

現在の発言は以下の通り。

SELECT 
  pjs.title,
  MATCH (pjs.title) AGAINST ('accountancy' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION) AS rel1,
  MATCH (pjs.description) AGAINST ('accountancy' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION) AS rel2,
  MATCH (
    pjs.benefits,
    pjs.experienceRequirements,
    pjs.incentives,
    pjs.qualifications,
    pjs.responsibilities,
    pjs.skills
  ) AGAINST ('accountancy' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION) AS rel3
FROM
  pxl_jobsearch AS pjs 
ORDER BY (rel1 * 5) + (rel2 * 1.5) + (rel3) DESC;
4

5 に答える 5

3

MySQL は全文検索があまり得意ではないため、他のエンジンを使用することをお勧めします。私のお気に入りは Sphinx ( http://sphinxsearch.com/ ) ですが、他にもあります。これらのサポートのほとんどは、すぐに使用できます。

大きなテーブルがあり、ステミングを使用する場合、MySQL のパフォーマンスはおそらく非常に悪くなります。

Sphinx を使用できない場合は、この php スクリプトを参照してくださいhttp://tartarus.org/~martin/PorterStemmer/php.txt

これにより、ステミング、およびステミングされた単語の検索を使用できます。

于 2012-09-11T07:44:30.613 に答える
1

検索エンジンは、ステミングと呼ばれるテキスト処理技術を実装することによってこれを行います。これを実装するライブラリはたくさんありますが、個人的にはSnowballステマーを使用していますが、十分に機能します。

私はMySqlの全文検索機能に精通していませんが、検索用語にステミングアルゴリズムを適用してみることができます。「会計コース」の例では、Snowballステマーは「アカウントコース」を返します。

于 2012-09-07T16:03:42.600 に答える
1

MySQLのSOUNDEX()機能はかなり近いものです。詳しくはこちらをご覧ください。

例:

create table test(id int auto_increment, a varchar(255), primary key(id));
insert into test(a) values
('accountancy'),
('accountant'),
('accountants'),
('accounting'),
('accountingc'),
('becounting'),
('asdf'),
('this is a test');

select 
test.*,
SOUNDEX(a),
SOUNDEX('accountancy')
FROM
test 
WHERE a SOUNDS LIKE 'accountancy';

これで解決しない場合は、レーベンシュタイン アルゴリズムを使用することをお勧めします。データベース管理者に、関数の作成を許可していることを伝えてください。もしそうなら、これが解決策です(私は関数を書きませんでした、クレジットは匿名に行きます):

DELIMITER //
CREATE FUNCTION levenshtein( s1 VARCHAR(255), s2 VARCHAR(255) )
RETURNS INT
DETERMINISTIC
BEGIN
DECLARE s1_len, s2_len, i, j, c, c_temp, cost INT;
DECLARE s1_char CHAR;
-- max strlen=255
DECLARE cv0, cv1 VARBINARY(256);
SET s1_len = CHAR_LENGTH(s1), s2_len = CHAR_LENGTH(s2), cv1 = 0x00, j = 1, i = 1, c = 0;
IF s1 = s2 THEN
RETURN 0;
ELSEIF s1_len = 0 THEN
RETURN s2_len;
ELSEIF s2_len = 0 THEN
RETURN s1_len;
ELSE
WHILE j <= s2_len DO
SET cv1 = CONCAT(cv1, UNHEX(HEX(j))), j = j + 1;
END WHILE;
WHILE i <= s1_len DO
SET s1_char = SUBSTRING(s1, i, 1), c = i, cv0 = UNHEX(HEX(i)), j = 1;
WHILE j <= s2_len DO
SET c = c + 1;
IF s1_char = SUBSTRING(s2, j, 1) THEN
SET cost = 0; ELSE SET cost = 1;
END IF;
SET c_temp = CONV(HEX(SUBSTRING(cv1, j, 1)), 16, 10) + cost;
IF c > c_temp THEN SET c = c_temp; END IF;
SET c_temp = CONV(HEX(SUBSTRING(cv1, j+1, 1)), 16, 10) + 1;
IF c > c_temp THEN
SET c = c_temp;
END IF;
SET cv0 = CONCAT(cv0, UNHEX(HEX(c))), j = j + 1;
END WHILE;
SET cv1 = cv0, i = i + 1;
END WHILE;
END IF;
RETURN c;
END//

再びテストデータ:

create table leven(id int auto_increment, a varchar(255), primary key(id));
insert into leven(a) values
('accountancy'),
('accountant'),
('accountants'),
('accounting'),
('accountingc'),
('becounting'),
('asdf'),
('this is a test')
;


select
leven.*,
levenshtein(leven.a, 'accountancy')
from
leven
where levenshtein(leven.a, 'accountancy') <= 3 /*or any value you like*/
于 2012-09-07T15:41:05.047 に答える
0

についてはよくわかりません。MATCHバリエーションのある列を選択したいときは、次のようにします

SELECT pjs.title
FROM pxl_jobsearch AS pjs
WHERE pjs.title LIKE 'account%'

私は主に SQL Server で作業していますが、MySQL もいくつか使用しています。これはMySQLでも機能すると思います。

于 2012-08-23T14:54:39.093 に答える
0

SQL を使用できますが、これはニーズに非常に役立ちます。文法的に近い単語ではなく、同じように聞こえるSOUNDEX()単語を検索します。非常によく似た 2 つのアプローチを使用できます。

  • %一般的な接尾辞を認識し、LIKE句の a に置き換えます。例を使用すると、accountancyになりaccount%ます。
  • 必要なすべてのバリエーションを含む「辞書」を作成し、それを PHP (stristr()関数)で使用accountancyWHERE value='accountancy' or value='accountant' or value='accountancies'ます。
于 2012-09-07T15:53:05.253 に答える