我有一个名为 $tagArr 的数组,用于存储标签。标签存储在数据库中,并以空格 (' ') 分隔。 这就是我从数据库获取标签的方式。
$tags=$row["tags"];
$tagArr = (explode(" ",$tags));
在此之后,我在数组 $tagArr 的索引处有元素
$tagArr[0], $tagArr[1], $tagArr[2], ...., $tagArr[n].
$lim
包含数组中元素的数量。我通过使用
$lim = count($tagArr);
考虑这个例如。
列“tag
”包含字符串:apple Orange葡萄
将其分解为数组后,索引将包含,
$tagArr[0] : apple
$tagArr[1] : orange
$tagArr[2] : mango
现在我有另一个 SQL 查询,我在其中选择具有相似标签的其他页面。这是不完整的查询,
$sql="SELECT title FROM posts WHERE tags LIKE '% <what will i place here?> %'";
我使用以下内容,它只会查找带有第一个标签的帖子
$sql="SELECT title, link, img FROM news WHERE tags LIKE '%$tagArr[0]%'";
如何正确执行此操作,以便我可以获取其中包含任何标签的帖子?这是任何带有标签苹果OR橙色OR芒果的帖子。
最佳答案
首先,您应该真正标准化您的数据结构,在单个字段中存储分隔值列表会带来像这样的麻烦。详情见 Is storing a delimited list in a database column really that bad? 的解答这里有关于SO的问题。
如果由于某种原因无法更改表结构,请使用 fulltext search代替 like,因为标签将是单独的单词。
在标签字段上创建全文索引:
alter table posts add fulltext index ft_tags (tags)
使用
match(...) ... against(... 在 bool 模式下) ...
fulltext search function in Boolean mode搜索标签:select * from posts where match(tags) against ('apple mango')
注意:您不必将 tags
字段的内容拆分为数组,因为 against()
接受以空格分隔的单词列表作为参数.
有3件事需要注意:
against()
只能接受字符串作为参数,因此如果您想搜索多组标签的相似帖子,则必须重复运行查询。如果您标准化了数据,这将不是问题。全文索引有一个最小字长参数,对于innodb默认设置为3,对于myisam表默认设置为4。如果标签短于最小字长,则必须在创建全文索引之前减小最小字长。
全文索引还使用停用词列表 - 文本中过于常见的单词(例如英语中的
the
),并且这些单词不会被编入索引。如果某个标签在该列表中,那么您必须将其删除。
所有这些都在链接的 MySQL 文档中进行了描述,并附有如何更改它们的说明。
关于mysql - 如何在 SQL 中获取与其他行具有相似标签的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44149364/