Samosprzężenia w usłudze Azure Cosmos DB for NoSQL
DOTYCZY: NoSQL
W usłudze Azure Cosmos DB for NoSQL dane są wolne od schematu i zwykle zdenormalizowane. Zamiast łączyć dane między jednostkami i zestawami, tak jak w relacyjnej bazie danych, sprzężenia występują w jednym elemencie. W szczególności sprzężenia są ograniczone do tego elementu i nie mogą występować w wielu elementach i kontenerach.
Porada
Jeśli okaże się, że potrzebujesz sprzężenia między elementami i kontenerami, rozważ przerobienie modelu danych , aby tego uniknąć.
Samosprzężenia z pojedynczym elementem
Przyjrzyjmy się przykładowi samosprzężenia w elemencie. Rozważ kontener z jednym elementem. Ten element reprezentuje produkt z różnymi tagami:
[
{
"id": "863e778d-21c9-4e2a-a984-d31f947c665c",
"categoryId": "e592b992-d453-42ee-a74e-0de2cc97db42",
"name": "Teapo Surfboard (6'10\") Grape",
"sku": "teapo-surfboard-72109",
"tags": [
{
"id": "556dc4f5-1dbd-41dc-9674-fda626e5d15c",
"slug": "tail-shape-swallow",
"name": "Tail Shape: Swallow"
},
{
"id": "ac097b9a-8a30-4fd1-8cb6-69d3388ee8a2",
"slug": "length-inches-82",
"name": "Length: 82 inches"
},
{
"id": "ce62b524-8e96-4999-b3e1-61ae7a672e2e",
"slug": "color-group-purple",
"name": "Color Group: Purple"
}
]
}
]
Co zrobić, jeśli chcesz znaleźć grupę kolorów tego produktu? Zazwyczaj należy napisać zapytanie z filtrem sprawdzającym każdy potencjalny indeks w tags
tablicy pod kątem wartości z prefiksem color-group-
.
SELECT
*
FROM
products p
WHERE
STARTSWITH(p.tags[0].slug, "color-group-") OR
STARTSWITH(p.tags[1].slug, "color-group-") OR
STARTSWITH(p.tags[2].slug, "color-group-")
Ta technika może szybko stać się nie do utrzymania. Złożoność lub długość składni zapytania zwiększa liczbę potencjalnych elementów w tablicy. Ponadto to zapytanie nie jest wystarczająco elastyczne, aby obsługiwać przyszłe produkty, które mogą mieć więcej niż trzy tagi.
W tradycyjnej relacyjnej bazie danych tagi zostaną rozdzielone na oddzielną tabelę, a sprzężenie między tabelami jest wykonywane z filtrem zastosowanym do wyników. W interfejsie API dla NoSQL możemy wykonać operację samosprzężenia w elemencie przy użyciu słowa kluczowego JOIN
.
SELECT
p.id,
p.sku,
t.slug
FROM
products p
JOIN
t IN p.tags
To zapytanie zwraca prostą tablicę z elementem dla każdej wartości w tablicy tagów.
[
{
"id": "863e778d-21c9-4e2a-a984-d31f947c665c",
"sku": "teapo-surfboard-72109",
"slug": "tail-shape-swallow"
},
{
"id": "863e778d-21c9-4e2a-a984-d31f947c665c",
"sku": "teapo-surfboard-72109",
"slug": "length-inches-82"
},
{
"id": "863e778d-21c9-4e2a-a984-d31f947c665c",
"sku": "teapo-surfboard-72109",
"slug": "color-group-purple"
}
]
Przeanalizujmy zapytanie. Zapytanie ma teraz dwa aliasy: p
dla każdego elementu produktu w zestawie wyników i t
dla tablicy sprzężonej tags
samodzielnie. Słowo *
kluczowe jest prawidłowe tylko do projekcji wszystkich pól, jeśli może wywnioskować zestaw danych wejściowych, ale teraz istnieją dwa zestawy danych wejściowych (p
i t
). Ze względu na to ograniczenie musimy jawnie zdefiniować zwracane pola jako id
i sku
z produktu wraz z tagami slug
. Aby ułatwić odczytywanie i zrozumienie tego zapytania, możemy usunąć id
pole i użyć aliasu dla pola tagu name
, aby zmienić jego nazwę na tag
.
SELECT
p.sku,
t.name AS tag
FROM
products p
JOIN
t IN p.tags
[
{
"sku": "teapo-surfboard-72109",
"tag": "Tail Shape: Swallow"
},
{
"sku": "teapo-surfboard-72109",
"tag": "Length: 82 inches"
},
{
"sku": "teapo-surfboard-72109",
"tag": "Color Group: Purple"
}
]
Na koniec możemy użyć filtru, aby znaleźć tag color-group-purple
. Ponieważ użyliśmy słowa kluczowego JOIN
, nasz filtr jest wystarczająco elastyczny, aby obsłużyć dowolną zmienną liczbę tagów.
SELECT
p.sku,
t.name AS tag
FROM
products p
JOIN
t IN p.tags
WHERE
STARTSWITH(t.slug, "color-group-")
[
{
"sku": "teapo-surfboard-72109",
"tag": "Color Group: Purple"
}
]
Samosądanie wielu elementów
Przejdźmy do przykładu, w którym musimy znaleźć wartość w tablicy, która istnieje w wielu elementach. W tym przykładzie rozważmy kontener z dwoma elementami produktu. Każdy element zawiera odpowiednie tagi dla tego elementu.
[
{
"id": "80d62f31-9892-48e5-9b9b-5714d551b8b3",
"categoryId": "19cd9b93-bdc5-4082-97fe-2c80c2fd77dd",
"categoryName": "Sleeping Bags",
"name": "Maresse Sleeping Bag (6') Ming",
"sku": "maresse-sleeping-bag-65503",
"tags": [
{
"id": "f50f3ee1-e150-4821-922b-ebe6ad82f313",
"slug": "bag-shape-mummy",
"name": "Bag Shape: Mummy"
},
{
"id": "8564fb66-63ea-464a-872a-7598433b9479",
"slug": "bag-insulation-down-fill",
"name": "Bag Insulation: Down Fill"
}
]
},
{
"id": "6e9f51c1-6b45-440f-af5a-2abc96cd083d",
"categoryId": "19cd9b93-bdc5-4082-97fe-2c80c2fd77dd",
"categoryName": "Sleeping Bags",
"name": "Vareno Sleeping Bag (6') Turmeric",
"sku": "vareno-sleeping-bag-65508",
"tags": [
{
"id": "e02502ce-367e-4fb4-940e-93d994fa6062",
"slug": "bag-insulation-synthetic-fill",
"name": "Bag Insulation: Synthetic Fill"
},
{
"id": "c0844995-3db9-4dbb-8d9d-d2c2a6151b94",
"slug": "color-group-yellow",
"name": "Color Group: Yellow"
},
{
"id": "f50f3ee1-e150-4821-922b-ebe6ad82f313",
"slug": "bag-shape-mummy",
"name": "Bag Shape: Mummy"
}
]
}
]
Co zrobić, jeśli chcesz znaleźć każdy element z kształtem torby mumii ? Możesz wyszukać tag bag-shape-mummy
, ale musisz napisać złożone zapytanie, które odpowiada dwóm cechom tych elementów:
Tag z prefiksem
bag-shape-
występuje w różnych indeksach w każdej tablicy. W przypadku śpiwora Vareno tag jest trzecim elementem (indeks:2
). W śpiworce Maresse tag jest pierwszym elementem (indeks:0
).Tablica
tags
dla każdego elementu ma inną długość. Śpiwór Vareno ma dwa tagi, podczas gdy śpiwór Maresse ma trzy.
JOIN
W tym miejscu słowo kluczowe jest doskonałym narzędziem do tworzenia produktu krzyżowego elementów i tagów. Sprzężenia tworzą kompletny produkt krzyżowy zestawów uczestniczących w sprzężeniu. Wynik jest zestawem krotki z każdą permutacją elementu i wartościami w tablicy docelowej.
Operacja sprzężenia na naszych przykładowych produktach śpiwórki i tagach tworzy następujące elementy:
Element | Tag |
---|---|
Maresse Śpiwór (6') Ming | Kształt torby: Mama |
Maresse Śpiwór (6') Ming | Izolacja worka: Wypełnienie w dół |
Vareno Śpiwór (6') Kurkuma | Izolacja worka: wypełnienie syntetyczne |
Vareno Śpiwór (6') Kurkuma | Grupa kolorów: żółty |
Vareno Śpiwór (6') Kurkuma | Kształt torby: Mama |
Oto zapytanie SQL i zestaw wyników JSON dla sprzężenia zawierającego wiele elementów w kontenerze.
SELECT
p.sku,
t.name AS tag
FROM
products p
JOIN
t IN p.tags
WHERE
p.categoryName = "Sleeping Bags"
[
{
"sku": "maresse-sleeping-bag-65503",
"tag": "Bag Shape: Mummy"
},
{
"sku": "maresse-sleeping-bag-65503",
"tag": "Bag Insulation: Down Fill"
},
{
"sku": "vareno-sleeping-bag-65508",
"tag": "Bag Insulation: Synthetic Fill"
},
{
"sku": "vareno-sleeping-bag-65508",
"tag": "Color Group: Yellow"
},
{
"sku": "vareno-sleeping-bag-65508",
"tag": "Bag Shape: Mummy"
}
]
Podobnie jak w przypadku pojedynczego elementu, można zastosować tutaj filtr, aby znaleźć tylko elementy pasujące do określonego tagu. Na przykład to zapytanie znajduje wszystkie elementy z tagiem o nazwie bag-shape-mummy
, aby spełnić początkowe wymaganie wymienione wcześniej w tej sekcji.
SELECT
p.sku,
t.name AS tag
FROM
products p
JOIN
t IN p.tags
WHERE
p.categoryName = "Sleeping Bags" AND
t.slug = "bag-shape-mummy"
[
{
"sku": "maresse-sleeping-bag-65503",
"tag": "Bag Shape: Mummy"
},
{
"sku": "vareno-sleeping-bag-65508",
"tag": "Bag Shape: Mummy"
}
]
Możesz również zmienić filtr, aby uzyskać inny zestaw wyników. Na przykład to zapytanie znajduje wszystkie elementy, które mają tag o nazwie bag-insulation-synthetic-fill
.
SELECT
p.sku,
t.name AS tag
FROM
products p
JOIN
t IN p.tags
WHERE
p.categoryName = "Sleeping Bags" AND
t.slug = "bag-insulation-synthetic-fill"
[
{
"sku": "vareno-sleeping-bag-65508",
"tag": "Bag Insulation: Synthetic Fill"
}
]