【问题标题】:Postgres pg_trgm how to compare similarity for array of stringsPostgres pg_trgm如何比较字符串数组的相似度
【发布时间】:2021-05-16 14:00:51
【问题描述】:

我正在尝试使用pg_trgm 进行字符串模糊匹配,我知道它可以这样使用:

SELECT * FROM artists WHERE SIMILARITY(name, 'Claud Monay') > 0.4;

其中标量值可用于与相似度进行比较。但是,我已经看到了将SIMILARITY 与字符串数组一起使用的这种方式:

SELECT * FROM artists WHERE 'Cadinsky' % ANY(STRING_TO_ARRAY(name, ' '));

它使用% 运算符,这是与0.3 的默认值进行比较的简写。我正在尝试找到正确的语法来使用ANY(STRING_TO_ARRAY(...)),但在第一种形式中,可以给出任意标量值来比较相似度。

这很可能只是正确使用 ANY 语法的一个简单问题,但我无法理解正确的形式是什么。

【问题讨论】:

    标签: sql postgresql fuzzy-search


    【解决方案1】:

    没有使用带有 3 个参数(字符串、字符串数组和相似度阈值)的 ANY 的语法。这样做的方法是将 pg_trgm.similarity_threshold 设置为您想要的值而不是默认值 0.3,然后使用% ANY

    如果您想在查询的不同部分使用不同的阈值,那么您对 ​​ANY 构造就不走运了。

    您始终可以定义自己的函数,但您可能无法让它使用索引。

    create or replace function most_similar(text, text[]) returns double precision 
    language sql as $$ 
        select max(similarity($1,x)) from unnest($2) f(x) 
    $$;
    
    SELECT * FROM artists WHERE most_similar('Cadinsky', STRING_TO_ARRAY(name, ' '))>0.4;
    

    【讨论】:

    • 是否可以用另一种不使用 ANY 函数的方式比较字符串数组的相似性和显式阈值?
    【解决方案2】:

    我不是数据库专家,也不擅长 SQL,但这是我的解决方案。

    我基本上使用一个名为 unnest() 的函数。因此,我可以遍历数组并检查每个项目的相似度值,然后将其与 similarity 输入进行比较,这是一个 float

    据我所知,使用 set pg_trgm.similarity_threshold=0.6; 之类的设置是全局设置。该问题专门要求明确的阈值

    另外,如果你创建了一个函数来完成这项工作,而该函数不是VOLATILE,而是STABLE,你不能使用 set pg_trgm.similarity_threshold。 (至少那是发生在我身上的事)。

    警告:我没有将我的方法与 (ANY) 方法的性能进行比较。

    示例代码:

    CREATE OR REPLACE FUNCTION your_function_name (input text, similarity float) RETURNS
    SELECT * FROM your_table_name
    WHERE EXISTS
       (SELECT
           FROM unnest(ARRAY['item','anotherItem', 'third-ish']) element
           WHERE SIMILARITY (input, element) > similarity
       );
    $ function $
    

    【讨论】:

      猜你喜欢
      • 2011-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-07
      相关资源
      最近更新 更多