2010-10-07 242 views
1

如果我有我的数据库的表中调用product_tags有2场:tag_idtag_name如何在MySQL中搜索“标签”?

这里是架构:

CREATE TABLE `product_tags` (
`tag_id` int(11) NOT NULL auto_increment, 
`tag_name` varchar(255) NOT NULL, 
PRIMARY KEY (`tag_id`), 
UNIQUE KEY `tag_name` (`tag_name`) 
) ENGINE=MyISAM AUTO_INCREMENT=84 DEFAULT CHARSET=utf8 

这里说的一些标签是:

  • 黄金
  • 黄钻
  • 白金
  • 玫瑰金
  • 钻石
  • 蓝钻
  • 粉色钻石
  • 黑钻

我想要做的字符串“黄金钻石带搜索“

我只想拉下面的标签:

  • 黄金
  • 钻石

因为只有这些标签是完全的字符串中。 黄色钻石都在字符串中,但不在一起,所以yellow diamond标签应该被忽略。


-Additionally如果可能的话

如果我做了搜索 “黄金蓝钻带

我只是想拉以下标签:

  • 黄色黄金
  • 频段
  • 蓝钻

diamond标签会被忽略,因为blue diamond标签将是比赛。


我该怎么做?

回答

5

编辑:

select 
    * 
from 
    product_tags P 
where 
    INSTR('yellow gold diamond band', P.tag_name) > 0 
+0

+1哇,这是伟大的! – 2010-10-07 16:53:09

+0

回答了第一个问题,但运行第二个输入查询我也得到了“钻石”标签。 – vulkanino 2010-10-07 16:53:41

+0

如何使用“继承”或什么的表?即具有两列的表格,两个外键插入到您的标记表中,指定一个替代另一个。例如,“蓝钻石”取代“钻石”。所以如果你得到结果并且你看到你有“蓝色钻石”,你可以从结果中删除“钻石”。 – EboMike 2010-10-07 17:01:44

1

直观,你可以建立一个算法遍历所有的搜索短语内连续字形成的可能的字的组合,然后找出其中哪些是你的标签表。例如:

黄金蓝钻带

的连续你可能的组合是:

  • 黄色
  • 黄金
  • 蓝色
  • 钻石
  • 黄金
  • 金蓝
  • 蓝钻
  • 钻石带
  • 黄金蓝色
  • 金蓝钻
  • 蓝钻带
  • 黄金蓝钻
  • 金蓝钻乐队
  • 黄金蓝钻石乐队

从这个整个列表,使其与原始名单,唯一的条件是:

  • 钻石
  • 黄金
  • 蓝钻

从这个名单你可以剔除任何重复相同词语的项目,偏好较短的假设t长期选项更具描述性。因此,消除这些条款后,您有:

  • 黄金
  • 蓝钻

这看起来像你想要的清单。现在,这种方法很有效,但随着搜索短语中术语数量的增加,它会变得非常缓慢。例如,只有你的5个词语产生了15个潜在的标签搜索。想象一下,如果你输入10个单词......

因此,我诚实的建议是,您使用某种标点符号来分隔搜索内的标签,从而通过简单地将搜索短语拆分为标点符号和搜索这些条款来更容易地找到标签,如下所示:

金黄色,蓝钻,带

用逗号分隔的列表,你现在只有3个搜索词,而不是15,使得它更容易搜索你的标签表。

0

你也许可以这样做:

WHERE @searchTerm LIKE CONCAT('%', tag_name, '%') 

不为许多标签的非常有效的,但它会在给出的简单情况下工作。

0

我想不出有什么好办法直接在SQL中做到这一点。

但是如果我是来实现它在我的应用程序的逻辑,这是伪逻辑很可能会像

1. Split the search string "yellow gold diamond band" using " " character. string[] search 
2. Take the 1st value from the array i.e. yellow in this case. 
3. Do a SELECT * FROM product_tags WHERE tag_name LIKE 'yellow%' 
4. This will return "yellow gold" and "yellow diamond" 
5. Loop through each of the results in 4 
    a. Split each of these results using " " string [] result 
    b. If the split array contains has count = 1, we found an exact match for "yellow". No need to search further 
    c. If the length of the array > 1, Match the search[1] with result[1] till either you have exhausted the split array and find a match or dont find one 
    d. If more than one match has been found, the longest match is considered 
6. Go back to step 2 and repeat for the next string i.e search[1] 
1

试试这个:

FROM product_tags 
WHERE `tag_name` REGEXP ? LIMIT