使用 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
对于每个匹配的标签,您会得到它被使用的次数。
然后,您首先根据标签是否与用户输入的内容完全匹配进行排序,然后根据使用情况进行排序。
当然,您必须参数化此查询,但我希望您能理解。
简介
我有一个项目,我们帮助 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
对于每个匹配的标签,您会得到它被使用的次数。 然后,您首先根据标签是否与用户输入的内容完全匹配进行排序,然后根据使用情况进行排序。 当然,您必须参数化此查询,但我希望您能理解。