我在零件编号表中进行了全文搜索。某些部件号带有连字符。
表引擎是使用MySQL 5.6的InnoDB。
我遇到的问题是,MySQL将连字符(-)当作单词分隔符。
所以我创建了一个新的MySQL字符集排序规则,而连字符被视为字母。
我遵循了本教程:http://dev.mysql.com/doc/refman/5.0/en/full-text-adding-collation.html
我使用链接底部的语法制作了一个测试表,但是我使用了InnoDB Engine。我搜索“ ----”并收到“语法错误,意外的'-'”]
但是,如果我将引擎更改为MyISAM,则会得到正确的结果。
如何使它与InnoDB引擎一起使用?
似乎在MySQL中向前迈出了一步,向后迈了了两步。
编辑:我发现此链接为5.6(http://dev.mysql.com/doc/refman/5.6/en/full-text-adding-collation.html),与使用InnoDB作为引擎的教程相同。
但是这是我的测试:
create table test (a TEXT CHARACTER SET latin1 COLLATE latin1_fulltext_ci, FULLTEXT INDEX(a)) ENGINE=InnoDB
添加了仅是“ ----”的行
select * from test where MATCH(a) AGAINST('----' IN BOOLEAN MODE)
语法错误,意外的'-'
删除表,MyISAM
create table test (a TEXT CHARACTER SET latin1 COLLATE latin1_fulltext_ci, FULLTEXT INDEX(a)) ENGINE=MyISAM
添加了仅是“ ----”的行
select * from test where MATCH(a) AGAINST('----' IN BOOLEAN MODE)
1个结果
编辑2,如果有助于视觉观察,这是我的2个测试:
InnoDb FULLTEXT搜索可能会将连字符视为停用词。因此,当到达第二个连字符时,它会期望一个单词,而不是连字符。这将解释“语法错误”。
为什么在MyISAM中不这样做,是因为InnoDB中FULLTEXT索引的实现是完全不同的,当然,它们仅在MySQL 5.6中为InnoDB添加了。
您对此可以做什么?看来您可以通过特殊表http://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html#sysvar_innodb_ft_user_stopword_table来影响停用词列表。这可以阻止MySQL将连字符当作停用词。
我最近遇到了这个确切的问题。我以前根据文档添加了自定义归类,并且正在使用MyISAM,并且运行良好。然后几周前切换到InnoDB,事情停止了。我尝试过:
innodb_ft_enable_stopword
设置为0
来禁用停用词最后,我采用了不同的方法,因为在全文索引方面,InnoDB似乎没有遵循与MyISAM相同的规则。对于某些人来说,这似乎很hacky,但这是我所做的:
search
列,其中包含我需要搜索的数据。此列具有全文索引,并且仅用于进行全文搜索而存在,在具有数百万行的表上,该列仍然非常快。-
列中的所有search
搜索/替换所有未使用的字符,这些字符被视为“单词”字符。请参阅此处有关此问题:https://dba.stackexchange.com/questions/248607/which-characters-are-considered-word-characters。弄清楚什么单词字符并不是那么容易,但是以下几个对我有用:Ω
œ
π
ß
µ
。这些字符可能未在您需要搜索的数据中使用,但解析器会将它们识别为可搜索的字符。就我而言,我将-
替换为Ω
。由于我只需要行ID,因此人眼看不出此列中的数据是什么。search
列数据和替换保持最新。就我而言,这很容易,因为应用程序中只有一个地方可以更新此特定表。也许可以为此使用触发器?-
替换我的查询中的Ω
。Voila。这是一个小提琴,演示:https://www.db-fiddle.com/f/x1WZpZP6wcqbTTvTEFFXYc/0
上述解决方法可能并不适用于每个应用程序,但希望对某些人有用。为InnoDB拥有一个真正的解决方案将非常好。