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";比";弹簧";并得到相应的排名。我想我可以做两个不同的搜索,并将排名乘以因子,但有更好的方法吗?

想要将不同的优先级与搜索词关联起来真的有那么奇怪吗?

生成SQL作为参考,老实说,我不认为这在Django现在是可能的,我们可能需要PostgreSQL大师的帮助。

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;

既然用这种方式挠痒痒很容易,为什么要发明其他机制呢?当权重是表的一部分,而不是查询的一部分时,你不可能真的这样做,所以它自己的机制更有意义。

最新更新