我们正在使用全文搜索来搜索公司的名称,一切都很顺利,直到我们有一个公司的名称中有一个与号,例如玛莎百货。
SELECT name FROM company WHERE MATCH (name) against ('M&S' IN BOOLEAN MODE);这不会返回任何结果,因为MySQL将“与”号视为布尔运算符。布尔模式是必需的,因此不能简单地将其关闭。
我正在寻找一种方法来转义&符号,这样MySQL就可以正确地处理它并找到记录。
放弃全文搜索,转而使用LIKE也不是一个好的选择
谢谢你的帮忙
发布于 2014-06-25 22:29:42
在用于全文搜索的排序规则中,&似乎不是一个单词字符。
因此,您必须创建自己的排序规则(或重新编译您的MySQL服务器),将&添加到单词字符列表中,就像我在MySQL文档( http://dev.mysql.com/doc/refman/5.0/en/fulltext-fine-tuning.html)中找到的那样:
如果要更改被视为单词字符的字符集,可以使用多种方法进行更改,如以下列表中所述。进行修改后,必须为包含所有全文索引的每个表重新生成索引。假设您想要将连字符('-')视为单词字符。使用以下方法之一:
修改MySQL源代码:在myisam/ftdefs.h中,请参见true_word_char()和misc_word_char()宏。将'-‘添加到其中一个宏并重新编译MySQL。
修改字符集文件:这不需要重新编译。true_word_char()宏使用“字符类型”表来区分字母和数字与其他字符。。您可以编辑其中一个字符集XML文件中的数组内容,以指定'-‘是一个“字母”。然后将给定的字符集用于全文索引。有关数组格式的信息,请参阅第10.3.1节“字符定义数组”。
为索引列使用的字符集添加新的排序规则,并更改列以使用该排序规则。有关添加排序规则的一般信息,请参阅第10.4节“向字符集添加排序规则”。有关特定于全文索引的示例,请参阅12.9.7节“为全文索引添加排序规则”。
更新:如果您使用的是latin1排序规则,请打开位于mysql/share/charsets/latin1.xml的XML文件。并在映射中找到相应的字符代码-在这种情况下,您可以将映射转换为小写或大写,因为这与与符号无关:
<lower>
<map>
00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F
20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F
30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F
40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F
60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F
70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F
80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F
90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F
A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF
B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF
E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF
F0 F1 F2 F3 F4 F5 F6 D7 F8 F9 FA FB FC FD FE DF
E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF
F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF
</map>
</lower>与符号的unicode是U+0026,在utf-8编码中是0x26,所以在地图中搜索26 -它在第3行,第7列。
然后在ctype-map中,将字符类型从10 (标点符号)更改为01 (小写字母):
<ctype>
<map>
00
20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20
20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
48 10 10 10 10 10 01 10 10 10 10 10 10 10 10 10
84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10
10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10
10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02
02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20
10 00 10 02 10 10 10 10 10 10 01 10 01 00 01 00
00 10 10 10 10 10 10 10 10 10 02 10 02 00 02 01
48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 10 01 01 01 01 01 01 01 02
02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02
02 02 02 02 02 02 02 10 02 02 02 02 02 02 02 02
</map>
</ctype>重新启动MySQL服务器,相应的排序规则会像处理小写字母一样处理&。
当然,最好先复制新的排序规则并将其重命名为XML-file,然后在Index.xml中复制并粘贴相应的行(不要忘记在XML标记中使用新的未使用的id ),并将它们链接到新的排序规则XML-file,这样就不会丢失原始排序规则。
你可以找到完整的文档,我从这里获得了大部分信息:http://dev.mysql.com/doc/refman/5.0/en/full-text-adding-collation.html
注意-对于所有使用MySQL5.7版本的用户,请使用未使用的排序规则id。mysql文章http://dev.mysql.com/doc/refman/5.0/en/fulltext-fine-tuning.html是针对MySQL5.5版本的。要获取最大排序规则Id,请使用以下查询-
SELECT MAX(ID) FROM INFORMATION_SCHEMA.COLLATIONS;发布于 2014-06-25 22:38:11
EDIT:,所以&将它分成两个单独的单词...因为它们是1个字母,所以不会返回任何内容。我用“Ma&Sa”测试过..我的ft_min_word_len = 4...它没有返回任何东西,所以由于字符串的长度大于4,但它没有返回,它必须将它拆分为两个单词…看起来northkildonan提出的建议是你必须要做的。
所以这可能是也可能不是答案..但我希望这对弄清楚这一点有帮助..尝尝这个。
首先:运行这条语句-- SHOW VARIABLES LIKE 'ft_min_word_len';并确认长度实际上是=2,如果是这样,我不确定它与长度超过4的单词有什么不同
第二:我这样做了,并得到了结果。
设置:
我在我的localhost数据库上设置了一个示例表...
create table company(
`id` int,
`name` varchar(55)
);
insert into company
(`id`, `name`)
values
(1, 'oracle'),
(2, 'microsoft'),
(3, 'M&S'),
(4, 'dell');测试:当ft_min_word_len =4时,进行了测试,显然它没有返回任何东西。
SELECT `name` FROM company WHERE MATCH (`name`) against ("M&S" IN BOOLEAN MODE);我不想尝试重新启动我的localhost数据库以将长度重置为2(以防我不小心弄乱了什么,因为我经常使用它)..
但我有了一个想法,那就是尝试查找长度超过4的公司名称,其中包含&。
更多设置:
insert into company
(`id`, `name`)
values
(5, 'Mary&Sasha');另一个测试:
SELECT `name` FROM company WHERE MATCH (`name`) against ("Mary&Sasha" IN BOOLEAN MODE); 此返回的http://screencast.com/t/Rx8mh98OUp
我也这样做了,以防校对弄乱了它,但我怀疑这就是问题所在。
排序规则:
ALTER TABLE company MODIFY
`name` VARCHAR(55)
CHARACTER SET latin1
COLLATE latin1_german2_ci;您还可以使用以下命令检查表的排序规则:
SHOW TABLE STATUS;希望这至少是一些帮助:)
发布于 2014-06-25 21:09:07
&在mysql中不是特殊字符,因此您可以存储和搜索表达式&,您可以按如下所示进行测试
SELECT name FROM `testing` WHERE name LIKE '%&%'另外,请尝试下面这样的东西来替换&。
SET @searchstring = 'M&S';
SET @searchstring = REPLACE(@searchstring,'&','&');
SELECT name FROM company WHERE MATCH (name) against (@searchstring IN BOOLEAN MODE);您还可以查看regexp。http://dev.mysql.com/doc/refman/5.1/en/regexp.html
这里&的用法如下所示。
mysql> SELECT '&' REGEXP '[[.ampersand.]]';下面的查询也为您提供了结果
SELECT *
FROM `testing`
WHERE `name` REGEXP CONVERT( _utf8 'M&S'
USING latin1 ) COLLATE latin1_german2_ci
LIMIT 0 , 30也请阅读这个帖子,也许你能比我更好地理解它。这是SQL,但他们似乎已经解决了问题http://forums.asp.net/t/1073707.aspx?Full+text+search+and+sepcial+characters+like+ampersand+。
对不起,我帮不了更多。
https://stackoverflow.com/questions/24238659
复制相似问题