Postgres查询/过滤JSONB与嵌套阵列

0

的问题

下面是我的样本要求

我想要的客户满足以下条件

  1. 在国家"xyz",代之间的2019年至2021年。
  2. 应当具有至少一个账户之间的平衡10000和13000和分是"abc"和交易的日期之间的20200110和20210625. 它的格式和存储数
  3. 应当具有至少一个地址在的状态"状态1"和pin码之间625001和625015

下表结构

        CREATE TABLE IF NOT EXISTS customer_search_ms.customer
        (
            customer_id integer,
            customer_details jsonb
        )
    

有可能是数以百万计的行表中。 我已经创建了杜松子酒指标的类型jsonb_ops在customer_details柱作为我们还要检查是否存在条件和范围比较

下面是一个样本数据在customer_data JSONB列

customer_id : 1

    {
        "customer_data": {
            "name": "abc",
            "incorporated_year": 2020,
            "country":"xyz",
            "account_details": [
                {
                    "transaction_dates": [
                        20180125, 20190125, 20200125,20200525
                    ],
                    "account_id": 1016084,
                    "account_balance": 2000,
                    "account_branch": "xyz"
                },
                {
                    "transaction_dates": [
                        20180125, 20190125, 20200125
                    ],
                    "account_id": 1016087,
                    "account_balance": 12010,
                    "account_branch": "abc"
                }
            ],
            "address": [
                {
                    "address_id": 24739,
                    "door_no": 4686467,
                    "street_name":"street1",
                    "city": "city1",
                    "state": "state1",
                    "pin_code": 625001
                },
                {
                    "address_id": 24730,
                    "door_no": 4686442,
                    "street_name":"street2",
                    "city": "city1",
                    "state": "state1",
                    "pin_code": 625014
                }
            ]
        }
    }

现在的查询,我已经写上

SELECT  c.customer_id,
        c.customer_details
FROM customer_search_ms.customer c
WHERE c.customer_details @@ CAST('$.customer_data.country ==  "xyz" && $.customer_data.incorporated_year >= 2019 && $.customer_data.incorporated_year <= 2021 ' AS JSONPATH)
AND c.customer_details @? CAST('$.customer_data.account_details[*] ? (@.account_balance >=  10000) ? (@.account_balance <=  13000) ?(@.account_branch ==  "abc") ? (@.transaction_dates >=  20200110) ? (@.transaction_dates <=  20210625)' AS JSONPATH)
AND c.customer_details @? CAST('$.customer_data.address[*] ? (@.state ==  "state1") ? (@.pin_code >=  625001) ? (@.pin_code <= 625015)  ' AS JSONPATH)

处理上述情况是这最好的方式编写。 是否有可能把所有的3个标准的(客户/帐户或地址)成一个表情? 该表将有数以百万计的行中。 我的意见具有它作为一个表达和打击该数据库将得到最好的业绩。 是否有可能结合这3条件作为一种表达

1

最好的答案

0

你的查询不给我错误您的报告。 相反,它的运行,但并得到的"错误的"结果相比你想要什么。 有几个错误,不是语法上的错误,但只要给了错误的结果。

你的第一jsonpath看起来很好。 这是一个布尔的表达, @@ 检查如果这种表达的产量 true.

你的第二jsonpath有两个问题。 它产生了一个名单的对象,这符合你条件。 但对象不是布尔,所以 @@ 会不高兴和返回SQL空,这是处理同一假如在这里。 而不是,你需要试验,如果这列表是空的。 这是什么 @? 不会的,所以使用,而不是的 @@. 还有,您的日期是存储为8位整数,但是你比他们到8个字符串。 在jsonpath,这类跨类型比较产率JSON空,这是处理同一假如在这里。 所以你要么需要改变储存串,或更改文本,他们是比较成整数。

你的第三jsonpath还有 @@ 问题。 和它的反向的类型问题,你有pin_code存储为串的,但你是检测它们对整数。 最后你有'pin_code'错误拼写,在一个发生。

2021-11-24 20:58:29

谢谢你简氏. 我已经纠正的代码和数据在原岗位。 由于机密性质,我不得不向后煮熟的数据并没有错这一点。 我不能再现错误的情况。 是否有任何好的方法,用于查询鉴于上述与3条件在其中的条款。 我的想法是如果我能够使它作为一个单一的条件,而不是3这样会更好。 任何指导,将是极大的帮助我。 感谢
Balaji Govindan

其他语言

此页面有其他语言版本

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................