我有一个名为$ tagArr的数组,用于存储标记。标签存储在由spaces (' ')
分隔的数据库中。
这就是我从DB中获取标签的方法。
$tags=$row["tags"];
$tagArr = (explode(" ",$tags));
在此之后,我在索引
的数组$ tagArr中有元素$tagArr[0], $tagArr[1], $tagArr[2], ...., $tagArr[n].
$lim
包含数组中的元素数。我通过使用
$lim = count($tagArr);
考虑这个例子。
专栏' tag
'包含字符串:apple orange grapes
将其explog到数组后,索引将包含
$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]%'";
如何正确执行此操作以便我可以获取其中包含任何标记的帖子?这是标记为apple OR orange OR mango的任何帖子。
答案 0 :(得分:0)
您可以在Query中使用正则表达式。
$row = "apple mango";
$tag_ex = '('.implode("|",explode(" ",$row)).')';
//$tag_ex will be >> (apple|mango)
//which you can use as regex in query.to match apple Or Mango in column
$sql = sprintf("SELECT title, link, img FROM news WHERE (tags REGEXP %s)",$tag_ex);
在$ sql之后,
SELECT title,link,img FROM news WHERE(标签REGEXP(apple | mango))
在标签栏中选择包含苹果或芒果的记录。
答案 1 :(得分:0)
首先,你应该真正规范化你的数据结构,在一个字段中存储分隔的值列表会引发像这样的麻烦。有关详细信息,请参阅此处有关Is storing a delimited list in a database column really that bad?问题的答案。
如果由于某种原因无法更改表格结构,请使用fulltext search代替,因为标签将是单独的单词。
在tags标签上创建全文索引:
alter table posts add fulltext index ft_tags (tags)
使用match(...) ... against(... in Boolean mode) ...
fulltext search function in Boolean mode搜索代码:
select * from posts where match(tags) against ('apple mango')
注意:您不必将tags
字段的内容拆分为数组,因为against()
会将以空格分隔的单词列表作为参数。
有三件事你需要注意:
against()
只能将字符串文字作为参数,因此如果要搜索多组标记的类似帖子,则必须重复运行查询。如果您将数据标准化,则不会出现问题。
全文索引具有最小字长参数,对于innodb,设置为3,默认情况下为myisam表设置为4。如果您的标签短于最小字长,则必须在创建全文索引之前减少的最小字长。
全文索引还使用停用词列表 - 文本中过于常见的单词(例如英语中的the
),并且这些单词未编入索引。如果该列表上有标签,则必须将其取下。
链接的MySQL文档中描述了所有这些以及如何更改它们的说明。