Dav*_*vis 2 postgresql similarity utf-8 plpgsql string-comparison
用户可以键入名称,系统应与文本匹配,即使用户输入或数据库字段包含重音(UTF-8)字符也是如此.这是使用该pg_trgm模块.
代码类似于以下内容:
SELECT
t.label
FROM
the_table t
WHERE
label % 'fil'
ORDER BY
similarity( t.label, 'fil' ) DESC
Run Code Online (Sandbox Code Playgroud)
当用户键入时fil,查询匹配filbert但不匹配filé powder.(因为重音字符?)
我试图实现一个unaccent函数并将查询重写为:
SELECT
t.label
FROM
the_table t
WHERE
unaccent( label ) % unaccent( 'fil' )
ORDER BY
similarity( unaccent( t.label ), unaccent( 'fil' ) ) DESC
Run Code Online (Sandbox Code Playgroud)
这只返回filbert.
建议:
CREATE EXTENSION pg_trgm;
CREATE EXTENSION unaccent;
CREATE OR REPLACE FUNCTION unaccent_text(text)
RETURNS text AS
$BODY$
SELECT unaccent($1);
$BODY$
LANGUAGE sql IMMUTABLE
COST 1;
Run Code Online (Sandbox Code Playgroud)
表中的所有其他索引都已删除.然后:
CREATE INDEX label_unaccent_idx
ON the_table( lower( unaccent_text( label ) ) );
Run Code Online (Sandbox Code Playgroud)
这只返回一个结果:
SELECT
t.label
FROM
the_table t
WHERE
label % 'fil'
ORDER BY
similarity( t.label, 'fil' ) DESC
Run Code Online (Sandbox Code Playgroud)
重写查询以确保返回两个结果的最佳方法是什么?
谢谢!
http://wiki.postgresql.org/wiki/What%27s_new_in_PostgreSQL_9.0#Unaccent_filtering_dictionary
http://postgresql.1045698.n5.nabble.com/index-refuses-to-build-td5108810.html
您没有使用pg_trgm模块提供的运算符类.我会创建一个像这样的索引:
CREATE INDEX label_Lower_unaccent_trgm_idx ON test_trgm USING gist (lower(unaccent_text(label)) gist_trgm_ops);
最初,我在这里有一个GIN索引,但后来我才知道GiST可能更适合这种查询,因为它可以返回按相似性排序的值.更多细节:
您的查询必须与索引表达式匹配才能使用它.
SELECT label
FROM the_table
WHERE lower(unaccent_text(label)) % 'fil'
ORDER BY similarity(label, 'fil') DESC -- it's ok to use original string here
Run Code Online (Sandbox Code Playgroud)
然而,根据%运算符,"filbert"和"filépowder"实际上并非与"fil"非常相似.我怀疑你真正想要的是这个:
SELECT label FROM the_table WHERE lower(unaccent_text(label)) ~~ '%fil%' ORDER BY similarity(label, 'fil') DESC -- it's ok to use original string here
这将找到包含搜索字符串的所有字符串,并根据%运算符首先对最佳匹配进行排序.
多汁的部分:表达式可以使用自PostgreSQL 9.1以来的GIN或GiST索引!我引用pg_trgm moule上的手册:
从PostgreSQL 9.1开始,这些索引类型也支持LIKE和ILIKE的索引搜索
如果你真的打算使用%运营商:
您是否尝试过门槛降低的相似性算%有set_limit():
SELECT set_limit(0.1);
Run Code Online (Sandbox Code Playgroud)
甚至更低?默认值为0.3.只是看看它是否是过滤额外匹配的阈值.
| 归档时间: |
|
| 查看次数: |
2167 次 |
| 最近记录: |