如何使用 Postgres 创建 trigram 或 ngram 词
How to create a trigram or ngram word with Postgres
我正在尝试使用 Postgres 创建基于三元组词的搜索。这个想法是实现一个简单的 did you mean
.
我想要一个 table 用八卦词而不是字符串。我知道 Postgres 为字符串提供了 trigram (pg_tgrm) 但我想完成这个:
` roses beautiful red colar sun`
八卦字:
[`roses beautiful red`, `beautiful red colar`, `red colar sun`]
在查询中如何最有效、最快速地实现这一目标。
每行 Select column from table -- transforming into the above
?
我试过:
with words as (
select unnest(regexp_split_to_array(`roses beautiful red colar sun`,'\s+')) as c from col
)
select c1.c || c2.c
from words c1
cross join words c2;
但我不知道如何将交叉连接用于更高级的场景。
您可以通过以下功能使用 PostgreSQL 全文搜索的强大功能:
CREATE FUNCTION phrase_trigram(regconfig, text) RETURNS tsquery
LANGUAGE plpgsql AS
$$DECLARE
words text[];
i integer;
result tsquery;
q tsquery;
BEGIN
/* split the string into an array of words */
words := regexp_split_to_array(, '[[:space:]]+');
FOR i IN 1..cardinality(words) - 2 LOOP
/* a phrase consisting of three consecutive words */
q := phraseto_tsquery(, array_to_string(words[i:i+2], ' '));
IF result IS NULL THEN
result := q;
ELSE
/* append with "or" */
result := result || q;
END IF;
END LOOP;
RETURN result;
END;$$;
构建一个全文搜索查询来测试您想要的“三词”短语。
这样使用:
SELECT to_tsvector('english', 'a text containing beautiful red colar')
@@ phrase_trigram('english', 'roses beautiful red colar sun'::text);
我正在尝试使用 Postgres 创建基于三元组词的搜索。这个想法是实现一个简单的 did you mean
.
我想要一个 table 用八卦词而不是字符串。我知道 Postgres 为字符串提供了 trigram (pg_tgrm) 但我想完成这个:
` roses beautiful red colar sun`
八卦字:
[`roses beautiful red`, `beautiful red colar`, `red colar sun`]
在查询中如何最有效、最快速地实现这一目标。
每行Select column from table -- transforming into the above
?
我试过:
with words as (
select unnest(regexp_split_to_array(`roses beautiful red colar sun`,'\s+')) as c from col
)
select c1.c || c2.c
from words c1
cross join words c2;
但我不知道如何将交叉连接用于更高级的场景。
您可以通过以下功能使用 PostgreSQL 全文搜索的强大功能:
CREATE FUNCTION phrase_trigram(regconfig, text) RETURNS tsquery
LANGUAGE plpgsql AS
$$DECLARE
words text[];
i integer;
result tsquery;
q tsquery;
BEGIN
/* split the string into an array of words */
words := regexp_split_to_array(, '[[:space:]]+');
FOR i IN 1..cardinality(words) - 2 LOOP
/* a phrase consisting of three consecutive words */
q := phraseto_tsquery(, array_to_string(words[i:i+2], ' '));
IF result IS NULL THEN
result := q;
ELSE
/* append with "or" */
result := result || q;
END IF;
END LOOP;
RETURN result;
END;$$;
构建一个全文搜索查询来测试您想要的“三词”短语。
这样使用:
SELECT to_tsvector('english', 'a text containing beautiful red colar')
@@ phrase_trigram('english', 'roses beautiful red colar sun'::text);