如何在MySQL中搜索“标签”?

如何在MySQL中搜索“标签”?,mysql,Mysql,如果我在数据库中有一个名为product_tags的表,它有两个字段:tag_id和tag_name 以下是模式: 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_I

如果我在数据库中有一个名为product_tags的表,它有两个字段:tag_id和tag_name

以下是模式:

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
在这里说一些标签:

黄金 黄色钻石 白金 玫瑰金 乐队 金刚石 蓝钻石 粉红钻石 黑钻石 我想搜索一下那串黄金钻石带

我只想拉下面的标签:

黄金 乐队 金刚石 因为只有那些标记正好在字符串中。黄色和菱形都在字符串中,但不在一起,因此应忽略黄色菱形标记

-如果可能的话,另外

如果我去寻找黄金蓝钻石戒指

我只想拉下面的标签:

黄金 乐队 蓝钻石 钻石标签将被忽略,因为蓝色钻石标签将是匹配项

我如何才能做到这一点?

编辑:

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


直观地说,您可以构建一个算法,该算法迭代搜索短语中由相邻单词组成的所有可能的单词组合,然后找到标记表中的单词组合。例如:

黄金蓝色钻石带

您可能的连续数据组合为:

黄的 金 蓝色 金刚石 乐队 黄金 金蓝色 蓝钻石 钻石带 黄金蓝 金蓝色钻石 蓝色钻石带 黄金蓝钻 金蓝色钻石带 黄金蓝色钻石带 从整个列表中,与原始列表匹配的术语只有:

金刚石 黄金 蓝钻石 乐队 从这个列表中,您可以剔除重复同一单词的任何项目,选择较长的选项而不是较短的选项,前提是较长的选项更具描述性。因此,在删除这些术语后,您有:

黄金 蓝钻石 乐队 这看起来像是您想要的列表。现在,这种方法是有效的,但随着搜索词组中词条数量的增加,它会变得非常缓慢。例如,仅您的5个术语就生成了15个潜在的标记搜索。想象一下如果你输入10个单词

因此,我真诚的建议是,在搜索中使用某种标点符号来分隔标记,从而通过简单地用标点符号拆分searh短语并搜索这些术语来更容易地找到标记,如下所示:

黄金,蓝钻石,乐队


使用逗号分隔的列表,您现在只有3个搜索词,而不是15个,这使得搜索标记表变得更加容易。

直观地说,您可以构建一个算法,迭代搜索短语中由连续词组成的所有可能的词组合,然后找到哪些词在标记表中。例如:

黄金蓝色钻石带

您可能的连续数据组合为:

黄的 金 蓝色 金刚石 乐队 黄金 金蓝色 蓝钻石 钻石带 黄金蓝 金蓝色钻石 蓝色钻石带 黄金蓝钻 金蓝色钻石带 黄金蓝色钻石带 从整个列表中,与原始列表匹配的术语只有:

金刚石 黄金 蓝钻石 乐队 从这个列表中,您可以剔除重复同一单词的任何项目,选择较长的选项而不是较短的选项,前提是较长的选项更具描述性。因此,在删除这些术语后,您有:

黄金 蓝钻石 乐队 这看起来像是您想要的列表。现在,这种方法是有效的,但随着搜索词组中词条数量的增加,它会变得非常缓慢。例如,仅您的5个术语就生成了15个潜在的标记搜索。想象一下如果你输入10个单词

因此,我真诚的建议是,在搜索中使用某种标点符号来分隔标记,从而通过简单地用标点符号拆分searh短语并搜索这些术语来更容易地找到标记,如下所示:

黄金,蓝钻石,乐队


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

您可能可以执行以下操作:

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

对于很多标签来说效率不是很高,但在给出的简单情况下,它会起作用。

您可能可以执行以下操作:

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

对于很多标记来说效率不是很高,但是在给出的简单情况下它可以工作。

我想不出任何好的方法直接在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]

我想不出有什么好方法可以直接在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]
试试这个:

FROM product_tags 
WHERE `tag_name` REGEXP ? LIMIT 
试试这个:

FROM product_tags 
WHERE `tag_name` REGEXP ? LIMIT 

这回答了第一个问题,但在使用第二个输入运行查询时,我也得到了菱形标记。带继承的表怎么样?i、 e.一个包含两列的表,将两个外键放入标记表中,指定其中一个取代oth
呃。例如,蓝色钻石取代钻石。所以如果你得到结果,你看到你有蓝色的钻石,你从结果中移除钻石。我也注意到了,仍然很好。Brian建议如何从列表中删除较短的重复单词diamond。实际上Brian和@EboMike的建议都很好,但是如果搜索字符串是带有钻石口音的蓝色钻石戒指,我希望两个标签都有。嗯,我不太确定该怎么办。。。也许最好把它们留在里面。也许,只需给blue diamond比diamond更大的权重/搜索相关性,因为它是一个较窄的类别。使用INSTR,您提取所有标签,然后检查一个标签是否在另一个标签中,如果是,则删除它,最后得到最长的标签。这回答了第一个问题,但是使用第二个输入运行查询时,我也会得到菱形标记。带继承的表怎么样?i、 e.一个具有两列的表,两个外键都插入标记表中,指定其中一个取代另一个。例如,蓝色钻石取代钻石。所以如果你得到结果,你看到你有蓝色的钻石,你从结果中移除钻石。我也注意到了,仍然很好。Brian建议如何从列表中删除较短的重复单词diamond。实际上Brian和@EboMike的建议都很好,但是如果搜索字符串是带有钻石口音的蓝色钻石戒指,我希望两个标签都有。嗯,我不太确定该怎么办。。。也许最好把它们留在里面。也许,只需给blue diamond比diamond更大的权重/搜索相关性,因为它是一个较窄的类别。使用INSTR,您提取所有标记,然后检查一个标记是否在另一个标记中,如果是,则删除它,最后得到最长的标记。