2011-10-03 52 views
2

我正在建立一个网站,要求包括复数的单词,但不包括单数的单词,以及包括更长的短语,但排除在其中找到较短的短语。PHP/MySQL - 包括复数但排除单数

例如:

  • 中搜索与“面包”应该在它“面包”,而不是“面包”或“读”返回结果。

  • 搜索“平装书”应该返回“平装书”结果,但不包含“平装书”或“书”。

我曾尝试查询:

SELECT * FROM table WHERE (field LIKE '%breads%') AND (field NOT LIKE '%bread%') 

...这清楚地返回任何结果,即使有与“面包”,并在其“面包”的记载。

我明白为什么这个查询失败(我告诉它包括和排除相同的字符串),但我想不出适用于代码来正确工作的正确逻辑。

+0

英语是一种不规则的语言。您将很难获得可以用简单的SQL查询的“复数”的可靠定义。另外,通配符搜索你使用它们的方式非常慢。对于任何尺寸合理的数据库,您都必须找到一种替代解决方案。 – Spudley

+2

数据库中的数据不够标准化。您需要将每个文本分成单词,并且每个单词都标记为单数或不单独。然后你可以在文本中只搜索单数的单词。 – hakre

+0

%是一个可以匹配任何东西的野性角色,所以在这种情况下使用时要小心。 –

回答

2

您应该考虑使用FULL TEXT SEARCH

这将解决您的面包/阅读问题。

我相信在这里使用通配符是没有用的。比方说,你正在使用'%read%',现在这也将返回breadbreads等,这就是为什么我建议Full Text Search

+0

尽管这样做会阻止您使用InnoDB表格。 – CD001

2

搜索%breads%就再也没有回到breadread,为“S”是为比赛所需要的字符。因此,只要消除和条款:

SELECT ... WHERE (field LIKE '%breads%') 
SELECT ... WHERE (field LIKE '%paperback book%'); 
+0

我相信在这里使用通配符是没有用的。假设你正在使用''%read%'',现在这还会返回'bread','breads'等等,这就是为什么我推荐**全文检索** –

+0

真的,但是在那时,重新搜索更小的单词,可以使用“而不是”额外的位。对于不能以简化形式出现的较长单词,此简化的where子句正常工作。 –

0

用MySQL,你可以使用,而不是像其REGEXP将让您对您的查询更好地控制...

SELECT * FROM table WHERE field REGEXP '\s+read\s+' 

这将至少执行绕字边界您的查询,并让您更好地控制您的匹配 - 尽管性能下降。