python - PostgreSQL 全文搜索权重/搜索词的优先级
问题描述
我通过 Django 在 PostgreSQL 中使用全文搜索。
我想将权重与搜索词相关联。我知道可以将不同的权重与不同的字段相关联,但我希望对搜索词具有不同的权重。
例子:
from core.models import SkillName
vector = SearchVector(
"name",
)
search = SearchQuery("Java") | SearchQuery("Spring")
search_result = (
SkillName.objects.all()
.annotate(search=vector)
.filter(search=search)
.annotate(rank=SearchRank(vector, search))
.order_by("-rank")
)
for s in search_result.distinct():
print(f"{s} rank: {s.rank}")
现在我希望“Java”比“Spring”更重要并获得相应的排名。我想我可以进行 2 次不同的搜索并将排名乘以因子,但有更好的方法吗?
想要将不同的优先级与 searchterms 相关联真的很奇怪吗?
生成的 SQL 供参考,老实说,我现在无论如何都不认为这在 Django 中是可能的,我们可能需要 PostgreSQL-guru 的帮助。
SELECT DISTINCT "core_skillname"."id",
"core_skillname"."name",
to_tsvector(COALESCE("core_skillname"."name", '')) AS "search",
ts_rank(to_tsvector(COALESCE("core_skillname"."name", '')), (plainto_tsquery('Java') || plainto_tsquery('Spring'))) AS "rank"
FROM "core_skillname"
WHERE to_tsvector(COALESCE("core_skillname"."name", '')) @@ (plainto_tsquery('Java') || plainto_tsquery('Spring'))
ORDER BY "rank" DESC;```
解决方案
应用带有权重的等级不需要两个查询,只需要在同一个查询中使用两个子表达式。
SELECT DISTINCT "core_skillname"."id",
"core_skillname"."name",
to_tsvector(COALESCE("core_skillname"."name", '')) AS "search",
ts_rank(to_tsvector(COALESCE("core_skillname"."name", '')), plainto_tsquery('Spring')) +
ts_rank(to_tsvector(COALESCE("core_skillname"."name", '')), plainto_tsquery('Java')) * 1.5 AS "rank"
FROM "core_skillname"
WHERE to_tsvector(COALESCE("core_skillname"."name", '')) @@ (plainto_tsquery('Java') || plainto_tsquery('Spring'))
ORDER BY "rank" DESC;
既然这样很容易挠自己的痒,为什么要发明其他机制来做到这一点呢?当权重是表的一部分,而不是查询的一部分时,你不能真正这样做,所以它自己的机制更有意义。
推荐阅读
- angular - 在 ngrx 中删除项目及其子项
- swift - 将 NSMutableAttributedString 应用于文本范围
- mysql - 如何填充缺失日期的数字?
- desktop - Panonlens - 图像未在桌面版本上加载
- azure - 何时使用 Azure Blob 存储与 Azure 文件共享?
- node.js - 需要代码sugg。让我的规范创建小型管理应用程序
- php - 在长结果中使用 SQL Server 数据库在 Laravel 中获取 500 错误
- svelte - 如何从组件内部调用组件的销毁?
- java - 如何在单个返回中返回布尔“if-then-else”语句
- ios - SwiftUI ZStack 对齐错误