Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Nel linguaggio di query i dati sono privi di schema e in genere denormalizzati. Anziché unire dati tra entità e set, come in un database relazionale, i join si verificano all'interno di un singolo elemento. In particolare, i join hanno come ambito tale elemento e non possono verificarsi tra più elementi e contenitori.
Suggerimento
Se è necessario creare un join tra elementi e contenitori, è consigliabile rielaborare il modello di dati per evitare questo anti-modello.
Self-join con un singolo elemento
Di seguito viene illustrato un esempio di self-join all'interno di un elemento. Si consideri un contenitore con un singolo elemento. Questo articolo rappresenta un prodotto con varie dimensioni:
[
{
"name": "Raiot Jacket",
"sizes": [
{
"key": "s",
"description": "Small"
},
{
"key": "m",
"description": "Medium"
},
{
"key": "l",
"description": "Large"
},
{
"key": "xl",
"description": "Extra Large"
}
]
}
]
Cosa succede se è necessario trovare prodotti con una dimensione specifica? In genere, è necessario scrivere una query con un filtro che controlla ogni potenziale indice nella sizes matrice per un valore con un prefisso. In questo esempio la query trova tutti i prodotti con dimensioni che terminano con Large:
SELECT
*
FROM
products p
WHERE
p.sizes[0].description LIKE "%Large" OR
p.sizes[1].description LIKE "%Large" OR
p.sizes[2].description LIKE "%Large" OR
p.sizes[3].description LIKE "%Large"
Questa tecnica può diventare insostenibile rapidamente. La complessità o la lunghezza della sintassi della query aumenta il numero di elementi potenziali nella matrice. Inoltre, questa query non è sufficientemente flessibile per gestire i prodotti futuri, che potrebbero avere più di tre dimensioni.
In un database relazionale tradizionale le dimensioni vengono separate in una tabella separata e viene eseguito un join tra tabelle con un filtro applicato ai risultati. Nel linguaggio di query è possibile eseguire un'operazione di self-join all'interno dell'elemento usando la JOIN parola chiave :
SELECT
p.name,
s.key,
s.description
FROM
products p
JOIN
s in p.sizes
Questa query restituisce una matrice semplice con un elemento per ogni valore nella matrice di tag.
[
{
"name": "Raiot Jacket",
"key": "s",
"description": "Small"
},
{
"name": "Raiot Jacket",
"key": "m",
"description": "Medium"
},
{
"name": "Raiot Jacket",
"key": "l",
"description": "Large"
},
{
"name": "Raiot Jacket",
"key": "xl",
"description": "Extra Large"
}
]
Suddividere la query. La query ha ora due alias: p per ogni elemento del prodotto nel set di risultati e s per la matrice self-join sizes . La * parola chiave è valida solo per proiettare tutti i campi se può dedurre il set di input, ma ora sono presenti due set di input (p e t). A causa di questo vincolo, è necessario definire in modo esplicito i campi restituiti come name dal prodotto insieme keya e description dalle dimensioni.
Infine, è possibile usare un filtro per trovare le dimensioni che terminano con Large. Poiché è stata usata la parola chiave , il JOIN filtro è sufficientemente flessibile per gestire qualsiasi numero variabile di tag:
SELECT
p.name,
s.key AS size
FROM
products p
JOIN
s in p.sizes
WHERE
s.description LIKE "%Large"
[
{
"name": "Raiot Jacket",
"size": "l"
},
{
"name": "Raiot Jacket",
"size": "xl"
}
]
Aggiunta automatica di più elementi
Si passerà a un esempio in cui è necessario trovare un valore all'interno di una matrice presente in più elementi. Per questo esempio, si consideri un contenitore con due elementi di prodotto. Ogni elemento contiene informazioni rilevanti colors per tale elemento.
[
{
"name": "Gremon Fins",
"colors": [
"science-blue",
"turbo"
]
},
{
"name": "Elecy Jacket",
"colors": [
"indigo-shark",
"jordy-blue-shark"
]
},
{
"name": "Tresko Pack",
"colors": [
"golden-dream"
]
}
]
Cosa succede se è necessario trovare ogni elemento con un colore che include blue nel nome? È possibile cercare manualmente la stringa blue, ma è necessario scrivere una query complessa che conti per due caratteristiche di questi elementi:
I colori con una
bluesottostringa si verificano in indici diversi in ogni matrice. Per ilElecy Jacketprodotto, il colore è il secondo elemento (indice:1). Per ilGremon Finsprodotto, il tag è il primo elemento (indice:0). IlTresko Packprodotto non contiene alcuna sottostringa.La
colorsmatrice per ogni elemento è una lunghezza diversa. IGremon Finsprodotti eElecy Jackethanno entrambi due colori, mentre ilTresko Packprodotto ne ha uno solo.
In questo caso, la JOIN parola chiave è un ottimo strumento per creare un prodotto incrociato degli elementi e dei colori. I join creano un prodotto incrociato completo dei set che partecipano al join. Il risultato è un set di tuple con ogni permutazione dell'elemento e i valori all'interno della matrice di destinazione.
Un'operazione di join sui prodotti e i colori di esempio crea gli elementi seguenti:
| Prodotto | Colore |
|---|---|
Gremon Fins |
science-blue |
Gremon Fins |
turbo |
Elecy Jacket |
indigo-shark |
Elecy Jacket |
jordy-blue-shark |
Tresko Pack |
golden-dream |
In questo esempio la query NoSQl usa la JOIN parola chiave per creare un prodotto incrociato e restituisce tutte le permutazioni:
SELECT
p.name,
c AS color
FROM
products p
JOIN
c in p.colors
[
{
"name": "Elecy Jacket",
"color": "indigo-shark"
},
{
"name": "Elecy Jacket",
"color": "jordy-blue-shark"
},
{
"name": "Gremon Fins",
"color": "science-blue"
},
{
"name": "Gremon Fins",
"color": "turbo"
},
{
"name": "Tresko Pack",
"color": "golden-dream"
}
]
Proprio come con il singolo elemento, è possibile applicare un filtro qui per trovare solo gli elementi che corrispondono a un tag specifico. Ad esempio, questa query trova tutti gli elementi con una sottostringa che contiene blue per soddisfare il requisito iniziale indicato in precedenza in questa sezione.
SELECT
p.name,
c AS color
FROM
products p
JOIN
c in p.colors
WHERE
c LIKE "%blue%"
[
{
"name": "Elecy Jacket",
"color": "jordy-blue-shark"
},
{
"name": "Gremon Fins",
"color": "science-blue"
}
]
Questa query può essere ulteriormente perfezionata per restituire solo i nomi dei prodotti che soddisfano il filtro. Questo esempio non proietta i valori di colore, ma il filtro funziona ancora come previsto:
SELECT VALUE
p.name
FROM
products p
JOIN
c in p.colors
WHERE
c LIKE "%blue%"
[
"Elecy Jacket",
"Gremon Fins"
]