我允许我的用户关注我平台上的某些类别和其他对象。例如,此系统中的每个类别都有一个唯一的 tag_id
(显示在括号中)。
Billiards (1)
Pool (2)
9-Ball (3)
8-Ball (4)
Snooker (5)
Cycling (6)
Mountain Biking (7)
Cross Country (8)
Downhill (9)
Dual Slalom (10)
Trials (11)
Road Racing (12)
Velodrome (13)
如果用户想要关注Cycling > Mountain Biking > Downhill
,我将保存9
、7
和6
到 user_tags
表:
用户标签
user_id | tag_id
---------|-----------
1 | 9
1 | 7
1 | 6
这意味着,如果有人在 Cycling (6)
中发布内容,以覆盖所有骑自行车的人,无论类型如何,那么它将在 Downhill
之后到达用户。
现在,我有 feed
和 feed_tags
表,其中包含所有帖子及其关联的标签:
提要
feed_id | title
---------|------------------------------------------
1044 | How to get into cross country racing.
1045 | How to get into downhill racing.
feed_tags
feed_id | tag_id
---------|----------
1044 | 8
1044 | 7
1044 | 6
1045 | 9
1045 | 7
1045 | 6
现在需要根据相关标签在 feed
表中搜索用户感兴趣的项目。
我的尝试:
首先,我得到一个用户标签的结果集并将其缓存以加快每次搜索的速度:
SELECT tag_id FROM user_tags WHERE user_id = 1;
这让我得到以下信息:
tag_id
---------
9
7
6
然后我循环遍历用户的标签模型来构建提要搜索查询的连接部分:
SELECT f.title
FROM feed AS f
// loop start
INNER JOIN feed_tags AS ft1 ON f.feed_id = ft1.feed_id
AND ft1.tag_id = 9
INNER JOIN feed_tags AS ft2 ON f.feed_id = ft2.feed_id
AND ft2.tag_id = 7
INNER JOIN feed_tags AS ft3 ON f.feed_id = ft3.feed_id
AND ft3.tag_id = 6
// loop end
这似乎适用于我拥有的非常少的测试数据。上面的查询只返回一个帖子,“How to get into downhill racing”。并且以下将它们都返回:
SELECT f.title FROM feed AS f
INNER JOIN feed_tags AS ft1 ON f.feed_id = ft1.feed_id
AND ft1.tag_id = 6
但是,我担心这不是正确的做法。我担心如果用户关注了 100 个标签,这种方法将不够有效,因为它是平台的高流量区域。我也在想,可能有更好的查询,它不涉及在循环中构建查询,而是将两个查询合二为一,既抓取用户的标签又交叉引用它们。
我选择的这个方法是可接受的还是可以改进?如果是,如何改进以及为什么?
最佳答案
在将类别系统更改为更简单的版本后,我设法自己回答了这个问题。我没有让类别系统中的每一层都可关注,而是像这样只关注端点:
Cycling [+]
Mountain Biking [+]
Cross Country (8)
Downhill (9)
Dual Slalom (10)
Trials (11)
这使得以下查询有效:
SELECT
f.feed_id,
f.title
FROM feed AS f
LEFT JOIN feed_tags AS ft ON ft.feed_id = f.feed_id
WHERE ft.tag_id IN (
SELECT
tag_id
FROM user_tags
WHERE user_id = 1
)
GROUP BY f.feed_id
关于mysql - 搜索带有特定标签的帖子,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55782137/