Rub*_*_ic 6 postgresql index full-text-search unaccent case-sensitive
我想知道在使用全文搜索时创建一个结合两个函数的索引是否有意义:lower(name)
而f_unaccent(name)
Wheref_unaccent
只是我的包装器,使 unaccent 函数不可变。
我确实有一个正在处理的索引:f_unaccent(name)
使用varchar_pattern_ops
. 我的问题是:组合lower
和unaccent
函数的索引是否会被 full_text_search 触发lower(f_unaccent(name))
。
我不知道该lower
函数是否对全文搜索算法有用。
首先,我们需要澄清一些事情。
这种类型的查询可以在 varchar/text pattern_ops 上工作,
foo LIKE 'bar%'
Run Code Online (Sandbox Code Playgroud)
foo LIKE '%bar%'
Run Code Online (Sandbox Code Playgroud)
只要您在查询中保持与索引中相同的序列,它们都可以处理函数表达式。
全文搜索是完全不同的东西。它通过截取词根、小写、删除停用词和一系列其他技巧将您的文本转换为词素。继续阅读:
不幸的是,虽然unaccent
只是“稳定”而不是“不可变”。因此,如果您尝试在其上创建索引,unaccent(text)
则会出现错误functions in index expression must be marked IMMUTABLE
. 我认为这就是您创建包装器的原因f_accent
,因为它在 Stack Overflow上的Erwins 答案中找到了。看起来像这样,
CREATE EXTENSION unaccent;
CREATE OR REPLACE FUNCTION f_unaccent(text)
RETURNS text AS
$func$
SELECT public.unaccent('public.unaccent', $1) -- schema-qualify function and dictionary
$func$
LANGUAGE sql
IMMUTABLE;
CREATE TABLE foo AS
SELECT 'asdf'::text AS mytext;
CREATE INDEX ON foo (lower(f_unaccent(mytext)) text_pattern_ops);
Run Code Online (Sandbox Code Playgroud)
或者,对于三元组,
CREATE INDEX ON foo
USING gin(lower(f_unaccent(mytext)) gin_trgm_ops);
Run Code Online (Sandbox Code Playgroud)
现在请记住,您必须执行这么长的序列lower(f_unaccent(mytext))
才能使其工作。
SELECT *
FROM foo
WHERE lower(f_unaccent(mytext)) LIKE '%whatever%';
Run Code Online (Sandbox Code Playgroud)
而不是那种方法,我会创建一个使用unaccent
和使用 FTS的字典。使用自定义词典,虽然它可能会做你想要的。FTS 将单词转换为标记,这使得搜索变得非常简单和快速。
CREATE EXTENSION unaccent; -- still required it plugs into FTS.
CREATE TEXT SEARCH CONFIGURATION mydict ( COPY = simple );
ALTER TEXT SEARCH CONFIGURATION mydict
ALTER MAPPING FOR hword, hword_part, word
WITH unaccent, simple;
Run Code Online (Sandbox Code Playgroud)
现在你应该能够
varchar_pattern_ops
或trigram
索引如果需要,在 tsvector 上创建GIST 或 GIN 索引
CREATE INDEX ON foo USING to_tsvector('mydict', mytext);
Run Code Online (Sandbox Code Playgroud)你可以在这里看到令牌和它在做什么,
select to_tsvector(
'mydict',
'Zoë and Renée are elected to the council of Cheese Eating Surrender Monkeys'
);
to_tsvector
-------------------------------------------------------------------------------------------------------------------------------------
'and':2 'are':4 'cheese':10 'council':8 'eating':11 'elected':5 'monkeys':13 'of':9 'renee':3 'surrender':12 'the':7 'to':6 'zoe':1
(1 row)
Run Code Online (Sandbox Code Playgroud)
你可以像这样简单地查询表,
SELECT *
FROM foo
WHERE to_tsvector('mydict', mytext) @@ 'cheese & council';
Run Code Online (Sandbox Code Playgroud)
你也不必使用simple
。如果该列仅包含一种语言的语句,您可以使用其他词典之一来简化内容并删除停用词。
归档时间: |
|
查看次数: |
6825 次 |
最近记录: |