如何在mysql match()中使用preg_replace()函数对()

时间:2014-01-14 08:31:06

标签: mysql preg-replace

我刚刚为mysql编译了preg_replace(),当我试图在全文搜索match()对()之前使用preg_replace()时它返回mysql语法错误。我的代码看起来类似于

select *, match(name, preg_replace('/[^a-z0-9A-Z]+/i', ' ', `column`)) against ('$name') as score
from files
order by score desc

...并触发此错误:

  

错误1064(42000):您的SQL语法有错误;检查   手册,对应右边的MySQL服务器版本   在'('/ [^ a-z0-9A-Z] + / i','',column))附近使用的语法   ('$ name')作为第1行'的分数

1 个答案:

答案 0 :(得分:2)

如果我们查看manual page for MATCH...AGAINST,我们可以看到MATCH()需要列列表:

  

MATCH (col1,col2,...) AGAINST (expr [search_modifier])   
[...]
  MATCH()采用逗号分隔的列表来命名要搜索的列

但是,您提供函数调用的结果:

match(name, preg_replace('/[^a-z0-9A-Z]+/i', ' ', `column`))

这背后的逻辑是全文搜索旨在使用在表列上创建的特殊索引来查找内容。您无法以随机字符串执行全文搜索。

Full-Text Restrictions章节中有进一步的解释:

  

MATCH()列列表必须与某些列列表完全匹配   表的FULLTEXT索引定义,除非此MATCH()为IN   MyISAM表上的BOOLEAN MODE。对于MyISAM表,布尔模式   搜索可以在非索引列上完成,尽管它们很可能   慢。


编辑:我不知道您的想法,但全文搜索的重点是对自然语言文本执行智能模糊匹配。如果您在搜索之前将“John'sfiancée”转换为“Johns fiance”,那么全文无法为您做任何事情。你确定你不想要旧的完全匹配吗?

WHERE preg_replace('/[^a-z0-9A-Z]+/i', ' ', `column`)='$name'

...或子模式匹配?

WHERE preg_replace('/[^a-z0-9A-Z]+/i', ' ', `column`) LIKE '%$name%'

无论如何,在任意字符串上执行全文的最佳方法是将它们存储到表中。它甚至会提高性能有两个原因:

  • 您无需重新计算每次搜索的值
  • 您实际上可以使用全文索引

您可以手动保持值同步(在每次插入或更新时)或写入触发器来执行此操作。