我们正在使用全文搜索来搜索公司名称,一切顺利,直到我们的公司名称为&符号,例如'M&安培; S'。
SELECT name FROM company WHERE MATCH (name) against ('M&S' IN BOOLEAN MODE);
由于MySQL将&符号视为布尔运算符,因此无法返回任何结果。需要布尔模式,因此不能简单地关闭它。
我正在寻找的是一种逃避&符号的方法,以便MySQL正确处理它并找到记录。
放弃全文搜索以支持LIKE
s也不是一个选项
感谢您的帮助
答案 0 :(得分:5)
似乎&
似乎不是您用于全文搜索的排序规则中的单词字符。
因此您必须创建自己的排序规则(或重新编译MySQL服务器),将&
添加到我在MySQL文档中找到的单词字符列表中(
http://dev.mysql.com/doc/refman/5.0/en/fulltext-fine-tuning.html):
如果要更改被视为单词的字符集 字符,您可以通过多种方式完成此操作,如中所述 以下列表。进行修改后,您必须重建 包含任何FULLTEXT索引的每个表的索引。假设 您希望将连字符(' - ')视为单词字符。 使用以下方法之一:
修改MySQL源:在myisam / ftdefs.h中,查看true_word_char() 和misc_word_char()宏。添加' - '到其中一个宏和 重新编译MySQL。
修改字符集文件:这不需要重新编译。该 true_word_char()宏使用“字符类型”表来区分 来自其他角色的字母和数字。 。您可以编辑内容 其中一个字符集XML文件中的数组 指定' - '是一个“字母。”然后使用给定的字符集 你的FULLTEXT索引。有关阵列的信息 格式,请参见第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>
&符号的&符号为U+0026
,并且在utf-8中对0x26
进行编码,因此在地图中搜索26
- 这是第3个第7栏。第页
然后在ctype
- 地图中将字符的类型从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
- 文件,并复制并粘贴Index.xml
中的相应行(不要忘记在XML
标记中使用新的未使用的ID,并将其链接到新的排序规则XML
- 文件,这样您就不会丢失原始排序规则。
您可以在此处找到我从中获取大部分信息的完整文档: http://dev.mysql.com/doc/refman/5.0/en/full-text-adding-collation.html
注意 - 对于使用Mysql 5.7版本的所有人,请使用未使用的排序规则ID。 mysql文章http://dev.mysql.com/doc/refman/5.0/en/fulltext-fine-tuning.html适用于Mysql 5.5版本。要获得最大归类ID,请使用以下查询 -
SELECT MAX(ID) FROM INFORMATION_SCHEMA.COLLATIONS;
答案 1 :(得分:0)
编辑:所以&amp;将它分成两个单独的单词......因为它们是1个字母,所以它不会返回任何内容。我用&#34; Ma&amp; Sa&#34; ...我的ft_min_word_len = 4进行了测试...它没有返回任何内容,因为该字符串的长度&gt; 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的公司的名称与&amp;在它。
更多设置:
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
我也这样做只是因为整理正在弄乱它,但我怀疑这是问题..
COLLATION STUFF:
ALTER TABLE company MODIFY
`name` VARCHAR(55)
CHARACTER SET latin1
COLLATE latin1_german2_ci;
您还可以使用以下方法检查表格排序规则:
SHOW TABLE STATUS;
希望这至少是一些帮助:)
答案 2 :(得分:-1)
&
不是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
在这里&amp;如下使用。
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+
抱歉,我无法提供更多帮助