full text search ranking documentation暗示
您可以编写自己的排名功能和/或将其结果与其他因素结合起来,以满足您的特定需求。
但我还没有找到任何关于如何构建自定义排名功能的示例。
具体来说,我还没有弄清楚如何在tsvector中提取符合给定tsquery的词条列表......如下所示:
> SELECT ts_matching_lexemes('cat in the hat'::tsvector, 'cat'::tsquery);
ts_matching_lexems
------------------
'cat':1
那么,我怎样才能找出tsvector中哪个词位与给定的tsquery相匹配?
答案 0 :(得分:2)
看起来ts_headline
函数已在内部执行此操作,但它在c源代码深处并输出一个字符串。但是,您可以使用它来为字符串解析结果准备输入(与c函数相比,这相对较慢):
<强>代码:强>
CREATE OR REPLACE FUNCTION ts_matching_lexemes(tsv tsvector, tsq tsquery)
RETURNS TSVECTOR AS
$$
WITH
proc AS (
SELECT
ts_headline(tsv::TEXT, tsq, 'StartSel = <;>, StopSel = <;>') tsh
)
, parts AS (
SELECT unnest(regexp_split_to_array(tsh, '<;>')) p FROM proc
)
, parts_enum AS (
SELECT p, lead(p, 1) OVER (), row_number() OVER () FROM parts
)
SELECT (string_agg(p || SUBSTRING(split_part(lead, ' ', 1) FROM 2), ' '))::tsvector
FROM parts_enum
WHERE row_number % 2 = 0
$$
LANGUAGE SQL;
<强> e.g:强>
select ts_matching_lexemes(to_tsvector('cat in the hat'), to_tsquery('cat'))
union
select ts_matching_lexemes(to_tsvector('cats and bikes in the hat'), to_tsquery('cat & bike'))
ts_matching_lexemes
tsvector
-------------------
'cat':1
'bike':3 'cat':1
<强> 注释 强>
tsvector
的文字表示传递给ts_headline
是为了减少冗余工作ts_headline(text, to_tsquery(...))
慢大约10倍,可以通过删除CTE来加速tsvector @@ tsquery