Postgres Zisťuje/filtrovanie JSONB s vnorených polí

0

Otázka

Nižšie je moje požiadavky na vzorku

Chcem zákazníkov, ktorí spĺňajú všetky podmienky nižšie

  1. V krajine "xyz", začlenený medzi 2019 až 2021.
  2. Mali by mať aspoň jeden účet s rovnováhu medzi 10000 a 13000 a pobočka je "abc" a transakcie dátumy medzi 20200110 a 20210625. To je naformátovaný a uložené ako čísla
  3. Mali by mať aspoň jednu adresu v štáte "state1" a pin kódy medzi 625001 a 625015

Nižšie je tabuľka štruktúra

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

Tam môže byť milióny riadkov v tabuľke. Vytvoril som GIN index typ jsonb_ops na customer_details stĺpci, ako by sme byť tiež kontrola na existenciu podmienky a rozsah porovnanie

Nižšie je ukážka údajov v customer_data JSONB stĺpec

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
                }
            ]
        }
    }

Teraz dotaz som napísal vyššie, je

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)

Zvládnuť vyššie scenár je to najlepší spôsob, ako písať. Je možné kombinovať všetky 3 kritériá to (customer/account/adresa) do jedného výrazu? Tabuľka bude mať milióny riadkov. Zastávam názor, mať ju ako jeden výraz a biť DB sa bude dať čo najlepší výkon. Je možné kombinovať tieto 3 podmienky ako jeden výraz

1

Najlepšiu odpoveď

0

Váš dotaz nedáva mi chyba, ktorú správa. Skôr, to beží, ale má dať "zle" výsledky v porovnaní s tým, čo hľadáte. Existuje niekoľko chyby v ňom, ktoré nie sú syntaktické chyby, ale len poskytovať nesprávne výsledky.

Váš prvý jsonpath vyzerá v poriadku. To je Boolovský výraz, a @@ kontroly, ak tento výraz výnosy true.

Druhý jsonpath má dva problémy. To prináša zoznam objektov, ktoré zodpovedajú vašim podmienkam. Ale objekty nie sú booleans, tak @@ bude nešťastný a vrátiť SQL NULL, ktoré je rovnaké ako nepravdivé tu. Namiesto toho musíte vyskúšať, ak tento zoznam je prázdny. To je to, čo @? robí, tak použite, že namiesto @@. Tiež, vaše dáta sú uložené ako 8-ciferné čísla, ale tie sú v porovnaním 8-znakové reťazce. V jsonpath, ako cross-typ porovnanie výnosu JSON null, ktoré je rovnaké ako nepravdivé tu. Takže buď budete musieť zmeniť skladovanie reťazce, alebo zmeniť literály sú v porovnaní s na celé čísla.

Tretej jsonpath má tiež @@ problém. A má na zadnej strane typ problém, máte pin_code uložené ako reťazce, ale ste ich testovanie proti celé čísla. Konečne ste "pin_code' chybne v jeden výskyt.

2021-11-24 20:58:29

Vďaka Janes. Som opravil kód a dáta v pôvodnom príspevku. Vzhľadom na dôverný charakter a mal som písať varené údajov a urobil chybu v tom. Nie som schopný reprodukovať chyba scenára. Je tam nejaký lepší prístup na dotaz uvedené vyššie s 3 podmienky, v ktorých doložky. Moje myslenie je, ak som schopný robiť to ako jediný stav, namiesto 3 to bude lepšie. Všetky usmernenia, ktoré budú veľmi užitočné pre mňa. Vďaka
Balaji Govindan

V iných jazykoch

Táto stránka je v iných jazykoch

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