【问题标题】:How to index a PostgreSQL JSONB flat text array for fuzzy and right-anchored searches?如何为模糊和右锚搜索索引 PostgreSQL JSONB 平面文本数组?
【发布时间】:2019-08-25 07:16:36
【问题描述】:

PostgreSQL 版本:9.6。

events 表有一个visitors JSONB 列:

CREATE TABLE events (name VARCHAR(256), visitors JSONB);

visitors 列包含一个“平面”JSON 数组:

["John Doe","Frédéric Martin","Daniel Smith",...].

events 表包含 1000 万行,每行有 1 到 20 个访问者。

是否可以对数组的值进行索引以执行有效的模式匹配搜索:

  1. 左锚:选择访问者匹配“John%”的事件
  2. 右锚:选择访问者匹配“%Doe”的事件
  3. unaccented:选择访问者匹配“Frederic%”的事件
  4. 不区分大小写:选择访问者匹配“john%”的事件

我知道 Postgres trigram 扩展 gin_trgm_ops 的存在可以为不区分大小写和右锚搜索创建索引,但我不知道如何为“flat”的内容创建 trigram 索引JSON 数组。

我阅读了Pattern matching on jsonb key/valueIndex for finding an element in a JSON array,但提供的解决方案似乎不适用于我的用例。

【问题讨论】:

  • 将其转换为 text 并使用带有三元索引的正则表达式。
  • @Laurenz Albe 感谢您的建议。我已经尝试将整个数组索引为文本 (create index events_visitors_trgm_idx on events using GIN ((visitors::text) gin_trgm_ops);) 但我们无法执行诸如 select * from events where visitors::text = 'John Doe' 之类的搜索,因为由于数组是纯文本,我们必须系统地使用不适合的 like '%John Doe%' 运算符我的用例。
  • 这就是我建议正则表达式的原因。搜索visitors ~ '\mJohn Doe\M'
  • 感谢您的澄清。这种正则表达式的方法效果很好,可以认为是一个答案。

标签: postgresql indexing jsonb


【解决方案1】:

您应该将jsonb 转换为text 并在其上创建一个三元索引:

CREATE EXTENSION pg_trgm;
CREATE INDEX ON events USING gin
   ((visitors::text) gin_trgm_ops);

然后对列使用正则表达式搜索。例如,要搜索John Doe,您可以使用:

SELECT ...
FROM events
WHERE visitors::text *~ '\mJohn Doe\M';

trigram 索引将支持此查询。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    • 2017-04-12
    • 1970-01-01
    • 2016-01-06
    • 2021-05-30
    相关资源
    最近更新 更多