我正在寻找一种在所有文档(及其相关值)中搜索特定表达式(然后是其一部分)的方法。最终顺序应该是:
- 完整表达式(在标题或内容中):使用 ILIKE 和 '%expression%'
- 其中一个词(在标题或内容中):在 tsvector 索引列上使用 tsquery
我有两个表:
- 文档(id [整数],标题[字符变化],title_search [tsvector])
- 值(id [整数],内容[字符变化],content_search [tsvector],id_document [整数])
这是我现在正在做的请求:
(SELECT id, title, content, title_search, content_search, ts_rank_cd(title_search, query) AS rank
FROM to_tsquery('lorem&ipsum|(lorem|ipsum)') query, documents
LEFT JOIN "values" ON id_document=id
WHERE (title ILIKE(unaccent('%lorem ipsum%')) OR content ILIKE(unaccent('%lorem ipsum%'))))
UNION (SELECT id, title, content, title_search, content_search, ts_rank_cd(title_search, query) AS rank
FROM to_tsquery('lorem&ipsum|(lorem|ipsum)') query, documents
LEFT JOIN "values" ON id_document=id
WHERE query @@ title_search)
UNION (SELECT id, title, content, title_search, content_search, ts_rank_cd(title_search, query) AS rank
FROM to_tsquery('lorem&ipsum|(lorem|ipsum)') query, documents
LEFT JOIN "values" ON id_document=id
WHERE query @@ content_search)
ORDER BY rank DESC, title ASC
通过这样做,我可以获得所有包含此表达式和/或其一部分的文档,但我无法正确排序这些文档。这是因为我依赖于 ts_rank 对 tsvector 字段的排名,该字段不能用于定义精确表达式。
所以我的问题是如何让它按预期工作?我使用全文搜索是错误的吗?
谢谢。
最佳答案
这有点尴尬,但我以前使用的解决方案是在您的各个子查询中包含一个额外的“排名”列。例如,第一个查询看起来像
select 1 as which_rank, id, title, ...
....
where title ILIKE(unaccent('%lorem ipsum%'))
OR content ILIKE(unaccent('%lorem ipsum%')))
那么第二个就是
select 2 as which_rank, id, title, ...
...
where query @@ title_search
第三个是
select 3 as which_rank, id, title, ...
...
where query @@ content_search
如果您在排序顺序中包含该排名值:
ORDER BY which_rank asc, rank DESC, title ASC
您可以确保首先列出第一个案例,然后列出第二个案例,然后再列出第三个案例。您也可以根据需要重新排列 1、2、3。
关于PostgreSQL 9.1 : Find exact expression in title,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21606879/