2014-02-17 31 views
0

我正在开发一个电子商务网站,使用Symfony2框架在PHP下编写;目前我需要开发一种方法为用户提供搜索产品的领域。MySQL - 通过在一个字段中搜索事件排序行

在每个产品中;我有一个名为'searchKeywords'的字段,它为此搜索引擎存储特殊关键字;因此,假设我们有以下产品的数据:

ProductId - keywords 
---------------------- 
1   child costume 
2   costume green 
3   child green 
  • 如果我要寻找的“孩子”,产品#1和#3应该显示,如果我搜索“服装”,产品#1应显示#2。
  • 问题在于:如果我搜索'服装绿色',所有三种产品都应该显示,因为它们都具有所有关键字,但是,我需要#2产品比其他产品更具关联性,因为它具有更多的搜索事件,所以产品#2应该高于其余。

所以我的问题是,有没有什么办法可以实现,而不使用PHP代码,只有MySQL?谢谢。

+0

您可能需要执行全文搜索https://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html –

+2

您是否考虑过正常化? – Strawberry

回答

1

如果每个输入关键字都在单独的变量中,则可以执行此操作。如果您将关键字用逗号分隔的空格代替:

select . . . 
where find _in_set($keyword1, keywords) > 0 or 
     find _in_set($keyword2, keywords) > 0 or 
     find _in_set($keyword3, keywords) > 0 
order by (find _in_set($keyword1, keywords) > 0 + 
      find _in_set($keyword2, keywords) > 0 + 
      find _in_set($keyword3, keywords) > 0 
     ); 

用空格,你可以这样做:

where concat(' ', $keywords, ' ') like concat(' %', $keyword1, '% ') or 
     concat(' ', $keywords, ' ') like concat(' %', $keyword2, '% ') or 
     concat(' ', $keywords, ' ') like concat(' %', $keyword3, '% ') 
order by concat(' ', $keywords, ' ') like concat(' %', $keyword1, '% ') + 
     concat(' ', $keywords, ' ') like concat(' %', $keyword2, '% ') + 
     concat(' ', $keywords, ' ') like concat(' %', $keyword3, '% ') 

额外的空间是防止“红”从匹配“重做”。

但是,你不应该在这样的列表中存储关键字。你应该有一个关联/联结表。这样的表格将具有ProductId的列和keyword的列。多个关键字将存储在不同的行上。有了这张表,查询,简直是:

from ProductKeywords pk 
where pk.keyword in ($keyword1, $keyword2, $keyword3) 
group by pk.ProductId 
order by count(*) desc; 

另一个优点这个疑问的是,它可以在ProductKeywords(keyword),你不能与你的存储关键字的方法做采取指数的优势。