如何使用mysql查找最相关的行?

问题描述 投票:0回答:1

我有一个包含数千行的MySQL文章表。每个文章行最多可以包含3个VARCHAR标记字段:tag1tag2tag3,每个字段都可以为空(在数据库中填充为NA

article表模式如下:

+------------+--------------+------+-----+-------------------+----------------+
| Field      | Type         | Null | Key | Default           | Extra          |
+------------+--------------+------+-----+-------------------+----------------+
| id         | int(11)      | NO   | PRI | NULL              | auto_increment |
| title      | varchar(100) | NO   |     | NULL              |                |
| body       | longtext     | NO   |     | NULL              |                |
| created_at | datetime     | NO   | MUL | CURRENT_TIMESTAMP |                           |
| visits     | int(11)      | NO   |     | 1                 |                |
| slug       | varchar(100) | NO   |     | NULL              |                |
| lasthit    | datetime     | YES  |     | CURRENT_TIMESTAMP |                |
| tag1       | varchar(100) | NO   |     | NA                |                |
| tag2       | varchar(100) | NO   |     | NA                |                |
| tag3       | varchar(100) | NO   |     | NA                |                |
+------------+--------------+------+-----+-------------------+----------------+

我想为每篇文章找到10 Relevant Articles的列表,因此该文章中具有较高相似标签数量的行应排在首位。因此,例如,如果ArticleA具有:

tag1 = "cat"
tag2 = "dog"
tag3 = "fish"

该查询应返回10个具有相同标签的文章,并且如果只有4行具有这3个标签,则其余结果必须来自具有2个公共标签的行,并且如果没有足够的行具有2个匹配标签,应返回1个匹配的标签。

我想知道实现此目标的最佳方法是什么?

mysql sql search
1个回答
1
投票

所以newA。*是10条匹配的文章的列表。取决于对articleA的先前articleID的输入。

SELECT newA.*
FROM articles articleA
JOIN articles newA
  ON newA.tag1 IN (articleA.tag1, articleA.tag2, articleA.tag3) OR
     newA.tag2 IN (articleA.tag1, articleA.tag2, articleA.tag3) OR
     newA.tag3 IN (articleA.tag1, articleA.tag2, articleA.tag3)
WHERE articleA.id = {some explict number}
   AND newA.id != articleA.id
ORDER BY
  (newA.tag1 IN (articleA.tag1, articleA.tag2, articleA.tag3) IS NOT NULL) +
  (newA.tag2 IN (articleA.tag1, articleA.tag2, articleA.tag3) IS NOT NULL) +
  (newA.tag3 IN (articleA.tag1, articleA.tag2, articleA.tag3) IS NOT NULL)
  DESC
LIMIT 10

[ORDER BY获取每个标签,并且X IN (...)为:

  • 1-是,值存在
  • 0-假,值不存在
  • NULL-newA.tagX为空。

'IS NOT NULL'将NULL变为0,因此可以将其添加。

此查询效率很低,因为它需要扫描整个文章以确定匹配项。

为了更高效地将article_tags表映射到具有id主键的tag,将导致此查询:

id,tag
© www.soinside.com 2019 - 2024. All rights reserved.