Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Na linguagem de consulta, os dados são livres de esquema e normalmente desnormalizados. Em vez de unir dados entre entidades e conjuntos, como faria em um banco de dados relacional, as junções ocorrem dentro de um único item. Especificamente, as junções têm escopo para esse item e não podem ocorrer em vários itens e contêineres.
Sugestão
Se você precisar unir itens e contêineres, considere retrabalhar seu modelo de dados para evitar esse antipadrão.
Auto-associação com um único item
Vejamos um exemplo de uma auto-junção dentro de um item. Considere um recipiente com um único item. Este item representa um produto com vários tamanhos:
[
{
"name": "Raiot Jacket",
"sizes": [
{
"key": "s",
"description": "Small"
},
{
"key": "m",
"description": "Medium"
},
{
"key": "l",
"description": "Large"
},
{
"key": "xl",
"description": "Extra Large"
}
]
}
]
E se precisar de encontrar produtos com um tamanho específico? Normalmente, você precisaria escrever uma consulta que tenha um filtro verificando cada índice potencial na matriz em busca de sizes um valor com um prefixo. Neste exemplo, a consulta localiza todos os produtos com um tamanho que termina com 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"
Esta técnica pode tornar-se insustentável rapidamente. A complexidade ou o comprimento da sintaxe de consulta aumenta o número de itens potenciais na matriz. Além disso, essa consulta não é flexível o suficiente para lidar com produtos futuros, que podem ter mais de três tamanhos.
Em um banco de dados relacional tradicional, os tamanhos seriam separados em uma tabela separada e uma junção entre tabelas é realizada com um filtro aplicado aos resultados. Na linguagem de consulta, podemos executar uma operação de auto-junção dentro do item usando a JOIN palavra-chave:
SELECT
p.name,
s.key,
s.description
FROM
products p
JOIN
s in p.sizes
Essa consulta retorna uma matriz simples com um item para cada valor na matriz tags.
[
{
"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"
}
]
Vamos detalhar a consulta. A consulta agora tem dois aliases: p para cada item de produto no conjunto de resultados e s para a matriz autoassociada sizes . A * palavra-chave só é válida para projetar todos os campos se puder inferir o conjunto de entradas, mas agora há dois conjuntos de entrada (p e t). Devido a essa restrição, devemos definir explicitamente nossos campos retornados como name do produto, juntamente com key, e description dos tamanhos.
Finalmente, podemos usar um filtro para encontrar os tamanhos que terminam com Large. Como usamos a JOIN palavra-chave, nosso filtro é flexível o suficiente para lidar com qualquer número variável de tags:
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"
}
]
Auto-junção de vários itens
Vamos passar para um exemplo onde precisamos encontrar um valor dentro de uma matriz que existe em vários itens. Para este exemplo, considere um contêiner com dois itens de produto. Cada item contém relevante colors para esse item.
[
{
"name": "Gremon Fins",
"colors": [
"science-blue",
"turbo"
]
},
{
"name": "Elecy Jacket",
"colors": [
"indigo-shark",
"jordy-blue-shark"
]
},
{
"name": "Tresko Pack",
"colors": [
"golden-dream"
]
}
]
E se você precisasse encontrar todos os itens com uma cor que inclui blue no nome? Você poderia pesquisar manualmente a cadeia de caracteres blue, mas precisaria escrever uma consulta complexa que levasse em conta duas características desses itens:
As cores com uma
bluesubstring ocorrem em índices diferentes em cada matriz. Para oElecy Jacketproduto, a cor é o segundo item (índice:1). Para oGremon Finsproduto, a tag é o primeiro item (índice:0). OTresko Packproduto não tem nenhum que contenha essa substring.A
colorsmatriz para cada item tem um comprimento diferente. OsGremon Finsprodutos têmElecy Jacketduas cores, enquanto oTresko Packproduto tem apenas uma.
Aqui, a JOIN palavra-chave é uma ótima ferramenta para criar um produto cruzado dos itens e cores. As junções criam um produto cruzado completo dos conjuntos que participam na junção. O resultado é um conjunto de tuplas com cada permutação do item e os valores dentro da matriz de destino.
Uma operação de junção em nossos produtos de amostra e cores cria os seguintes itens:
| Produto | Cor |
|---|---|
Gremon Fins |
science-blue |
Gremon Fins |
turbo |
Elecy Jacket |
indigo-shark |
Elecy Jacket |
jordy-blue-shark |
Tresko Pack |
golden-dream |
Este exemplo de consulta NoSQl usa a JOIN palavra-chave para criar um produto cruzado e retorna todas as permutações:
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"
}
]
Assim como com o item único, você pode aplicar um filtro aqui para encontrar apenas itens que correspondam a uma tag específica. Por exemplo, essa consulta localiza todos os itens com uma substring que contém blue para atender ao requisito inicial mencionado anteriormente nesta seção.
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"
}
]
Essa consulta pode ser refinada ainda mais para apenas retornar os nomes dos produtos que atendem ao filtro. Este exemplo não projeta os valores de cor, mas o filtro ainda funciona conforme o esperado:
SELECT VALUE
p.name
FROM
products p
JOIN
c in p.colors
WHERE
c LIKE "%blue%"
[
"Elecy Jacket",
"Gremon Fins"
]