0

我目前有一个用于我的博客的标签系统。每个博客都被插入到博客表中,标签被插入到标签表中。标签表有一个 blog_id 列,用于将每个标签链接到一个博客项目。

所以假设我们有:

Blog table:
id - name 
20 - a nice blog post about product x

Tag table:
id - blog_id - tag
12 - 20 - nice
13 - 20 - product x

我有一个搜索功能,可以根据搜索字符串搜索标签,效果很好。

但我想扩展查询以搜索多个标签,并按最佳匹配排序。搜索多个标签不会有问题,因为我可以分解搜索字符串并循环遍历它,但是按最佳匹配排序它是我无法弄清楚的。

假设我有 3 篇博文,每篇都有以下标签:
1.sunny,in-ear,earphones,review
2.pear,out-ear,earphones,review
3.pear,in-ear,earphones,review

用户搜索“梨形入耳式耳机”,我希望结果的顺序为:
3.(因为 3 个标签匹配)
1.(因为 2 个标签匹配)
2.(因为 1 个标签匹配)

这是查询的样子:

选择`b`。*
FROM (`博客` b)
在哪里 (
    b.name LIKE '%pear 入耳式耳机%'
    或者
    b.ID IN (
        选择 bt.blog_id
        FROM blog_tags bt
        WHERE bt.tag LIKE '%梨形入耳式耳机%'
        和 bt.blog_id = b.id
        )
    )
ORDER BY `b`.`date` desc


谁能帮帮我?
我看过“全文搜索”,但这不是一个选项,因为我的表是 InnoDB。

提前致谢!

4

2 回答 2

3

我个人喜欢使用Solr进行文本匹配。您可以创建这些复杂的公式,将名称中的匹配权重高于标签中的匹配,反之亦然。它也匹配复数形式。因此,如果我搜索butterflies它会找到butterfly匹配项。

这是另一个查询,可以帮助您按频率排序博客标签。此查询将获取标签中至少有一个匹配项的所有博客项目。它将按匹配的标签数量排序

SELECT *
FROM blog b
JOIN (
    SELECT blog_id, COUNT(*) as matches 
    FROM tags 
    WHERE tag in ('pear', 'in-ear', 'earphones') 
    GROUP BY blog_id
) t
ON t.blog_id = b.blog_id
ORDER BY matches desc

您可以像这样添加特定字符串的匹配数:

SELECT *,
    t.matches + 
    COALESCE((LENGTH(b.`title`)-LENGTH(REPLACE(b.`title`,'pear','')))/LENGTH('pear'),0) + 
    COALESCE((LENGTH(b.`title`)-LENGTH(REPLACE(b.`title`,'in-ear','')))/LENGTH('in-ear'),0) + 
    COALESCE((LENGTH(b.`title`)-LENGTH(REPLACE(b.`title`,'earphones','')))/LENGTH('earphones'),0) AS total_matches,
FROM blog b
LEFT JOIN (
    SELECT blog_id, COUNT(*) as matches 
    FROM tags 
    WHERE tag in ('pear', 'in-ear', 'earphones') 
    GROUP BY blog_id
) t
ON t.blog_id = b.blog_id
ORDER BY total_matches desc
ORDER BY 

请注意,对于所有这些匹配和事物,此查询可能会很慢。我仍然建议使用像 Solr 这样的索引软件

于 2013-06-20T20:32:17.543 回答
2

以下查询计算与特定列表匹配的标签数量,并按匹配数量排序:

select b.*
from blog b join
     blog_tags bt
     on b.id = bt.blog_id
where bt.tag in ('pear', 'in-ear', 'earphones')
group by blog_id
order by COUNT(*) desc;

请注意,like原始查询中的使用不正确。所有标签都不包含字符串'pear in-ear earphones'

于 2013-06-20T20:43:21.237 回答