Postgres Query/filtro JSONB con matrici nidificate

0

Domanda

Qui di seguito la mia requisito del campione

Ho bisogno di clienti che soddisfano tutte le seguenti condizioni

  1. In paese "xyz", costituita tra 2019 al 2021.
  2. Dovrebbe avere almeno un account con un saldo tra 10000 e 13000 e ramo è "abc" e le date di transazione tra 20200110 e 20210625. È formattata come numero
  3. Dovrebbe avere almeno un indirizzo nello stato "stato1" e codici pin tra 625001 e 625015

Qui di seguito è la struttura della tabella

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

Ci possono essere milioni di righe nella tabella. Ho creato GIN indice di tipo jsonb_ops sul customer_details colonna come ci sarebbe anche un controllo per l'esistenza di condizioni di gamma e di confronto

Di seguito è riportato un esempio di dati in customer_data JSONB colonna

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

Ora la query che ho scritto sopra è

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)

Per gestire scenario di cui sopra, è il modo migliore per scrivere. È possibile combinare tutti i 3 criteri (cliente/conto/indirizzo) nell'espressione? La tabella avrà milioni di righe. Io sono del parere che avere come espressione e di colpire il DB darà le migliori prestazioni. È possibile combinare queste 3 condizioni come espressione

1

Migliore risposta

0

La query non mi da l'errore si riferisce. Piuttosto, corre, ma il "male" risultati, rispetto a ciò che si desidera. Ci sono diversi errori che non sono errori di sintassi, ma basta dare risultati errati.

Il primo jsonpath guarda bene. Si tratta di una espressione Booleana, e @@ verifica se l'espressione rendimenti true.

Il secondo jsonpath ha due problemi. Restituisce una lista di oggetti che soddisfano le tue condizioni. Ma gli oggetti non sono booleane, così @@ sarà infelice e restituire NULL, che è considerato come falso qui. Invece, è necessario verificare se la lista è vuota. Questo è ciò che @? fa, in modo da utilizzare che invece di @@. Inoltre, le date vengono memorizzate come 8 cifre, numeri interi, ma si sono confrontati 8-stringhe di caratteri. In jsonpath, traversa confronti di tipo rendimento JSON null, che è considerato come falso qui. Quindi è necessario modificare la memorizzazione di stringhe o modificare i valori letterali sono a confronto in numeri interi.

Il terzo jsonpath ha anche la @@ problema. Ed è l'inverso del tipo di problema, si ha la pin_code memorizzati come stringhe, ma il test contro interi. Infine, si ha 'pin_code' errori di ortografia in una ricorrenza.

2021-11-24 20:58:29

Grazie Jane. Ho corretto il codice e dati nel post originale. A causa della natura confidenziale dovevo post cotto dati errore che. Io non sono in grado di riprodurre lo scenario di errore. C'è qualche metodo migliore per query di data di cui sopra con 3 condizioni nella clausola where. Il mio pensiero è che se io sono in grado di farlo come una sola condizione, invece di 3 sarà migliore. Ogni guida sarà di grande aiuto per me. Grazie
Balaji Govindan

In altre lingue

Questa pagina è in altre lingue

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