Postgres 三元组匹配对于特定字符表现得很奇怪

Llo*_*ell 3 postgresql full-text-search pattern-matching

我正在使用 pg_trgm 运行查询,但在使用符号差异进行搜索时得到很多 1 匹配。我有以下查询:

SELECT my_column, similarity('$ Hello', my_column) AS sml
FROM my_table
WHERE my_column % '$ Hello'
ORDER BY sml DESC, my_column;
Run Code Online (Sandbox Code Playgroud)

在 中my_table,我有以下内容:

- Hello
? Hello
| Hello
$ Hello
! Hello
!? Hello
Run Code Online (Sandbox Code Playgroud)

它们都以 1 的相似性匹配返回。我是否需要转义“$”或类似的内容?

Erw*_*ter 6

其他答案澄清了三元组相似性仅基于字母数字字符。这就是为什么你所有的例子都 100% 匹配。

您仍然可以使用 trigram GiST 或 GIN 索引,并使用其他表达式建立所需的排序顺序ORDER BY。对于您演示的案例:

SELECT my_column, similarity('$ Hello', my_column) AS sml
FROM   my_table
WHERE  my_column % '$ Hello'
ORDER  BY sml DESC
        , my_column <> '$ Hello'       -- !
        , my_column;
Run Code Online (Sandbox Code Playgroud)

布尔表达式按此排序顺序my_column <> '$ Hello'计算为FALSETRUENULL- 。因此,精确匹配(考虑所有字符)是第一位的。并且这个查询仍然可以使用三元组索引。三元组 GiST 索引(仍然)甚至支持使用. 有关的:LIMIT

您可以做更多事情,具体取决于您的具体用例和要求。例子:

...
ORDER  BY sml DESC
        , my_column <> '$ Hello'
        , my_column !~ '\$ Hello'            -- note $ escaped with \$
        , levenshtein(my_column , '$ Hello')
        , my_column;
Run Code Online (Sandbox Code Playgroud)

在相同的三元组相似度内,首先对精确匹配进行排序,然后对包含精确短语的字符串进行排序。在每个子组中,首先匹配较短的编辑距离。按字母顺序作为最后的决胜局。有关的:

最后但并非最不重要的一点是,您标记了全文搜索。但是您的示例是基于三元组相似性(由附加模块提供pg_trgm),这是一个很大程度上不同的概念,具有完全独立的基础设施和运算符。您可能需要实际的全文搜索(以及短语搜索?):

但标点字符在 FTS 中仍然被视为噪音并被删除。同样的问题”。ts_debug()显示文本搜索配置如何对给定字符串中识别的标记进行分类(simple示例中的配置)。

SELECT * FROM ts_debug('simple', '? Hello %&/( 123');
Run Code Online (Sandbox Code Playgroud)

它从“默认”解析器(目前是唯一的)开始,将所有这些解析为噪音......


Lau*_*lbe 5

SELECT show_trgm('$ Hello');

            show_trgm            
---------------------------------
 {"  h"," he",ell,hel,llo,"lo "}
(1 row)

SELECT show_trgm('- Hello');

            show_trgm            
---------------------------------
 {"  h"," he",ell,hel,llo,"lo "}
(1 row)
Run Code Online (Sandbox Code Playgroud)

在计算三元组之前,所有非字母数字字符都会从字符串中删除。

这就是字符串具有相似性 1 的原因。

您不能使用三元组索引来搜索符号。

该文档的第一句话中有它(强调我的):

该模块提供了用于根据三元匹配确定字母数字文本pg_trgm相似度的函数和运算符