Postgres jsonb高级搜索

时间:2018-04-24 09:55:15

标签: postgresql jsonb postgresql-10

我已经发布了一个类似的问题,但我必须准确一点......

这是原帖:[Postgres jsonb search in array with greater operator (with jsonb_array_elements)

如果我总结一下,

这是数据库声明(简化):

CREATE TABLE documents (
    document_id int4 NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    data_block jsonb NULL,
    type varchar(10)
);

这是插入的一个例子。

INSERT INTO documents (document_id, data_block)
VALUES(878979, 
    {"COMMONS": {"DATE": {"value": "2017-03-11"}},
     "CARS": [
         {"MODEL": {"value": "FERRARI F40"}}, 
         {"MODEL": {"value": "PORSCHE CAYENNE"}},
         {"MODEL": {"value": "FERRARI Testarossa"}}
     ]}, 'garage');
INSERT INTO documents (document_id, data_block)
VALUES(977656, 
    {"INVOICE": {"TOTAL_AMOUNT": {"value": "100.00"}},
     "PAYABLE_INVOICE_LINES": [
         {"AMOUNT": {"value": 75.00}},
         {"AMOUNT": {"value": 25.00}}
     ]}, 'invoices');
INSERT INTO documents (document_id, data_block)
VALUES(345, 
    {"INVOICE": {"TOTAL_AMOUNT": {"value": "200.00"}},
     "PAYABLE_INVOICE_LINES": [
         {"AMOUNT": {"value": 125.00}},
         {"AMOUNT": {"value": 75.00}}
     ]}, 'invoices');

事实上,我可以在我的JSONB列中存储任何内容,现在我想用特定的运算符进行搜索。

查询示例:

  • PAYABLE_INVOICE_LINES中至少有一行大于100.00的所有文件:data_block.PAYABLE_INVOICE_LINES.AMOUNT> 100.00

  • 所有带有CARS行的文档以' FERRARI'开头。 :data_block.CARS.MODEL喜欢' FERRARI%'

  • 所有TOTAL_AMOUNT = 100.00

  • 的文件
  • COMMONS.DATE>所有文件" 2018年4月30日"

  • 列表中CARS.MODEL的所有文件(' PORSCHE CAYENNE')

  • data_block.PAYABLE_INVOICE_LINES.AMOUNT位于100.00和150.00之间的所有文件

Bref,我想查询我想要的一切。我希望通过排序限制为50个结果。

我的数据库包含数百万行,我遇到了一些性能问题...

我使用EXISTS实现了解决方案:

select *
from documents d
where exists (
  select 1
  from jsonb_array_elements(d.data_block -> 'PAYABLE_INVOICE_LINES') as pil
  where (pil->'AMOUNT'->>'value')::decimal >= 1000)
limit 50;

这很好,但还不够......有些疑问很慢。 > 20秒。

我不知道文件的结构。我们可以插入汽车,发票,身份证,客户可以创建自己的结构。 因此,我无法轻松创建索引,也无法创建函数来准备结果。

当搜索JSON对象中的数组时,查询非常慢。喜欢PAYABLE_INVOICE_LINES。

您对如何提高性能有想法吗?

0 个答案:

没有答案