MYSQL-仅从标记搜索中检索完整单词


MYSQL - Retrieving Only Full Words From Tag Search

我正在尝试从mysql数据库中检索条目,其中数据库中的关键字对应于文章的标题或文章的标签。目前我正在使用instr,但这还不够具体,因为我发现对于较短的关键字,检索到了太多不相关的结果——也就是说,我试图检索标题或标签列表中有单词"art"的条目,但它最终检索到了其他带有单词"article"的条目。

我有以下表格结构。数据库有一个预定义的标记列表。每个物品类别都从主标签列表中分配了多个标签:

tags_tbl (overall tags list)
    tt_tag_id (pk) int
    tt_tag  varchar
category_tag_assignments_tbl (the category which a tag is assigned to)
    cta_id (pk) int
    cta_tag_for_id (fk to tags_tbl.tt_tag_id) int
    cat_for_id (fk to category table) int

我的问题是:

SELECT * FROM tags_tbl INNER JOIN category_tag_assignments_tbl ON tags_tbl.tt_tag_id = category_tag_assignments_tbl.cta_tag_for_id WHERE instr('The Article Title' , tags_tbl.tt_tag) > 0 OR instr('these,are,article,tags' , tags_tbl.tt_tag) > 0 

我如何才能在文章标题和文章标签中搜索完整的单词,而不在字符串可能出现的地方检索更长的单词,同时还要考虑到标签列表由不带空格的逗号分隔这一事实?我想尽量减少php处理的数量——我无法控制标题和标签的实际呈现,因为这些是由外部源提供的,除非我提前用php修改它们。

我正在考虑合并以下regex,我在stackoverflow上找到了它,但我不知道如何在这种情况下应用它,因为我正在我的搜索词中搜索(很抱歉,我知道措辞笨拙,但我想不出其他怎么说):

WHERE tags_tbl.tt_tag REGEXP '[[:<:]]art[[:>:]]'

谢谢!

首先,您可以考虑在布尔模式下进行全文搜索。这可能比任何基于字符串的解决方案都要好。

也就是说,你可以通过用分隔符包围标签和搜索字符串来做你想做的事:

SELECT *
FROM tags_tbl INNER JOIN
     category_tag_assignments_tbl
     ON tags_tbl.tt_tag_id = category_tag_assignments_tbl.cta_tag_for_id
WHERE concat(' ', 'The Article Title', ' ') like concat('%', tags_tbl.tt_tag, '%')OR
      concat(',', 'these,are,article,tags', ',') like concat('%', tags_tbl.tt_tag, '%')

最后一个表达式实际上可以通过使用find_in_set()来简化,对于以下where子句:

WHERE concat(' ', 'The Article Title', ' ') like concat('%', tags_tbl.tt_tag, '%')OR
      find_in_set(tags_tbl.tt_tag, 'these,are,article,tags') > 0

实际上,你也可以把它用于第一个表达式——如果标题中有逗号,这会很方便:

WHERE find_in_set(tags_tbl.tt_tag, replace('The Article Title', ' ', ',') or
      find_in_set(tags_tbl.tt_tag, 'these,are,article,tags') > 0;