PostgreSQL:带有jsonb列的pg_trgm全文搜索?

Ole*_*ann 5 postgresql

我有一个带有jsonb列的表,用于存储变量数据。我想搜索此列并找到片段(前导或尾随空格)。我想我知道如何对文本列执行此操作,但无法绕过如何对文本列执行此操作jsonb

我想实现两种方案:

  1. 仅搜索jsonb列内的特定键(例如 data->>company
  2. 搜索整jsonb

对于文本列,我使用pg_trgm生成杜松子酒索引。

安装扩展pg_trgm:

CREATE extension if not exists pg_trgm;
Run Code Online (Sandbox Code Playgroud)

创建表和索引:

CREATE TABLE tbl (
    col_text  text,
    col_json  jsonb
);

CREATE INDEX table_col_trgm_idx ON tbl USING gin (col_text gin_trgm_ops);
Run Code Online (Sandbox Code Playgroud)

查询示例:

SELECT * FROM tbl WHERE col_text LIKE '%foo%';   -- leading wildcard
SELECT * FROM tbl WHERE col_text ILIKE '%foo%';  -- works case insensitive as well
Run Code Online (Sandbox Code Playgroud)

用jsonb列尝试相同操作失败。如果我尝试索引整个列

CREATE INDEX table_col_trgm_idx ON tbl USING gin (col_json gin_trgm_ops);
Run Code Online (Sandbox Code Playgroud)

我得到错误

ERROR (datatype_mismatch): operator class "gin_trgm_ops" does not accept data type jsonb
Run Code Online (Sandbox Code Playgroud)

(这有道理)。如果我尝试仅索引jsonb列的一个键,我也会收到错误消息:

CREATE INDEX table_col_trgm_idx ON tbl USING gin (col_json->>company gin_trgm_ops);
Run Code Online (Sandbox Code Playgroud)

错误:

ERROR (syntax_error): syntax error at or near "->>"
Run Code Online (Sandbox Code Playgroud)

我用这个答案通过@欧文- Brandstetter修改作为参考。非常感谢任何帮助(不,到目前为止,我还不想实现Elasticsearch :))。


编辑:像这样创建索引实际上有效:

CREATE INDEX table_col_trgm_idx ON tbl USING gin ((col_json->>'company') gin_trgm_ops);
Run Code Online (Sandbox Code Playgroud)

而且查询它也不会导致错误:

SELECT * FROM tbl WHERE col_json->>'company' LIKE '%foo%'; 
Run Code Online (Sandbox Code Playgroud)

但是结果总是空的