Postgres Dotazování/filtrování JSONB s vnořené pole

0

Otázka

Níže je můj vzorek požadavek

Chci, aby zákazníci, kteří splňují všechny níže uvedené podmínky

  1. V zemi "xyz", začleněna mezi 2019 až 2021.
  2. By měl mít alespoň jeden účet s rovnováhou mezi 10000 a 13000 a pobočka je "abc" a transakčních dat mezi 20200110 a 20210625. To je formátována a uložena jako číslo
  3. Měla by mít alespoň jednu adresu ve státě "state1" a pin kódy mezi 625001 a 625015

Níže je tabulka

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

Tam může být miliony řádků v tabulce. Vytvořil jsem GIN index typ jsonb_ops na customer_details sloupci, jak by být také kontrola na existenci, podmínky a rozsah srovnání

Níže je ukázka dat v customer_data JSONB sloupec

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

Teď dotaz jsem napsal výše, je pro

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ádnout výše uvedené scénáře je to nejlepší způsob, jak psát. Je možné kombinovat všechny 3 kritéria (zákazníka/účet/adresu) do jednoho výrazu? Tabulka bude mít miliony řádků. Jsem toho názoru, že to jako jeden výraz a bít DB vám poskytne nejlepší výkon. Je možné kombinovat tyto 3 podmínky jako jeden výraz

1

Nejlepší odpověď

0

Tvůj dotaz mi nedává vás chybová zpráva. Spíše to běží, ale dát "špatné" výsledky porovnání s tím, co chcete. Existuje několik chyb, které v něm nejsou chyby syntaxe, ale jen dát špatné výsledky.

První jsonpath vypadá v pořádku. To je Logický výraz, a @@ kontroluje, zda ten výraz výnosy true.

Váš druhý jsonpath má dva problémy. Vede seznam objektů, které odpovídají vašim podmínkám. Ale objekty nejsou boolean, takže @@ bude nešťastná a vrátit SQL NULL, což je zacházeno stejně jako falešné. Místo toho, budete muset vyzkoušet, jestli ten seznam je prázdný. To je to, co @? ano, tak použít místo @@. Také, vaše data jsou uloženy jako 8-ciferných čísel, ale ty jsou jejich porovnání s 8-znakové řetězce. V jsonpath, jako je cross-type, srovnání výnosu JSON hodnotu null, což je zacházeno stejně jako falešné. Takže budete buď muset změnit úložiště na řetězce, nebo změňte literály jsou ve srovnání s na celá čísla.

Třetí jsonpath má také @@ problém. A to má opačný typ problému, máte pin_code uloženy jako řetězce, ale testování je proti celá čísla. Konečně máte pin_code' chybně v jednom výskytu.

2021-11-24 20:58:29

Díky Janes. Opravil jsem kód a údaje v původním příspěvku. Vzhledem k důvěrné povaze musel jsem po vařené dat a udělal chybu v tom, že. Nejsem schopen reprodukovat chyba scénáře. Je tam lepší přístup pro dotaz výše uvedených 3 podmínek v klauzuli where. Moje myšlení je, jestli jsem schopen to udělat jako jeden stav, místo 3 to bude lepší. Veškeré pokyny bude velká pomoc pro mě. Díky
Balaji Govindan

V jiných jazycích

Tato stránka je v jiných jazycích

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