使用 like 运算符并按子查询排序

Use like operator and order by sub query

简介

我有一个项目,我们帮助 IT 社区组织更好的 IT 聚会(就像 meetup.com 但仅针对 IT 社区)称为 https://codotto.com/

我们正在开发一项新功能,我们想在其中显示某些标签的使用次数。该算法应该像 Whosebug 的算法一样工作。您输入 javascript,您会得到一个列表,其中包含与您的查询匹配的标签(按最常用的标签排序)。

我目前正在使用 Laravel,但我会 post 原始查询,以便 mysql 向导在可能的情况下更容易帮助我:)

问题

我有以下 tables

标签table

id  name
1   javascript
2   javascript-tools
3   javascript-security

group_has_tags table

group_id  tag_id
1         2
2         2
2         3

我们有标签 javascript-tools 使用了两次,javascript-security 使用了一次,而 javascript 根本没有使用。

现在,如果用户搜索 javascript,他应该首先搜索 javascript(因为它是直接匹配),然后是按用途排序的其余标签。

在Laravel中这是我的代码(简化的ofc)

$tags = Tag::withCount('groups')
  ->orderBy('groups_count', 'DESC')
  ->where('name', 'LIKE', 'javascript%')
  ->get(2);

问题是因为我只 return 返回 2 结果,javascript 没有被包含在结果中,即使这是用户字面上写的

对于 mysql 魔术师,这里是原始查询

select
  `tags`.*,
  (
    select
      count(*)
    from
      `meetups`
        inner join `meetup_has_tags` on `meetups`.`id` = `meetup_has_tags`.`meetup_id`
    where
        `tags`.`id` = `meetup_has_tags`.`tag_id`
  ) as `meetups_count`
from
  `tags`
where
    `title` LIKE 'javascript%'
order by
  `meetups_count` desc
limit
  2 offset 0

问题

这里的主要 objective 是 return 与用户最相关的结果。他写 javascript 并且 javascript 先出现,然后是不太“相关”的结果。我找到的方法是按标签使用次数排序。

有没有解决方案可以让我“请先获取与此查询匹配的结果,然后 return 最相关的结果”?

我所说的“最相关”结果只是指“用户正在寻找什么”。如果他写“javascript”它应该return“javascript”然后是“javascript-tools”(因为“javascript-tools”被使用了两次但是用户实际上是在搜索“javascript”)

这是您的查询:

SELECT * FROM
(SELECT tags.*,COALESCE((SELECT COUNT(*) FROM group_has_tags WHERE tag_id = tags.id),0) AS usage
FROM tags
WHERE title LIKE 'javascript%') AS tmp
ORDER BY tmp.name = 'javascript' DESC,usage DESC

对于每个匹配的标签,您会得到它被使用的次数。 然后,您首先根据标签是否与用户输入的内容完全匹配进行排序,然后根据使用情况进行排序。 当然,您必须参数化此查询,但我希望您能理解。