Sdílet prostřednictvím


Samoobslužná spojení – Dotazovací jazyk ve službě Cosmos DB (v Azure a prostředcích infrastruktury)

V dotazovacím jazyce jsou data bez schématu a obvykle denormalizována. Místo spojení dat mezi entitami a sadami, jako byste v relační databázi, došlo k spojení v rámci jedné položky. Spojení jsou konkrétně vymezena na danou položku a nemůžou nastat napříč několika položkami a kontejnery.

Návod

Pokud zjistíte, že se potřebujete spojit mezi položkami a kontejnery, zvažte přepracování datového modelu, abyste se vyhnuli tomuto anti-vzoru.

Spojení se svým držitelem s jednou položkou

Podívejme se na příklad připojení sebe sama v rámci položky. Zvažte kontejner s jednou položkou. Tato položka představuje produkt s různými velikostmi:

[
  {
    "name": "Raiot Jacket",
    "sizes": [
      {
        "key": "s",
        "description": "Small"
      },
      {
        "key": "m",
        "description": "Medium"
      },
      {
        "key": "l",
        "description": "Large"
      },
      {
        "key": "xl",
        "description": "Extra Large"
      }
    ]
  }
]

Co když potřebujete najít produkty s konkrétní velikostí? Obvykle byste museli napsat dotaz, který má kontrolu filtru pro každou potenciální index v sizes poli pro hodnotu s předponou. V tomto příkladu dotaz najde všechny produkty s velikostí, která končí Largena :

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"

Tato technika se může rychle stát nepotenitelným. Složitost nebo délka syntaxe dotazu zvyšuje počet potenciálních položek v poli. Tento dotaz navíc není dostatečně flexibilní pro zpracování budoucích produktů, které můžou mít více než tři velikosti.

V tradiční relační databázi by se velikosti rozdělily do samostatné tabulky a spojení křížové tabulky se provádí s filtrem použitým na výsledky. V dotazovacím jazyce můžeme pomocí klíčového slova provést operaci automatického JOIN spojení v rámci položky:

SELECT
  p.name,
  s.key,
  s.description
FROM
  products p
JOIN
  s in p.sizes

Tento dotaz vrátí jednoduchou matici s položkou pro každou hodnotu v poli značek.

[
  {
    "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"
  }
]

Pojďme dotaz rozdělit. Dotaz teď má dva aliasy: p pro každou položku produktu v sadě výsledků a s pro pole připojené sizes k sobě. Klíčové * slovo je platné pouze pro projektovat všechna pole, pokud může odvodit vstupní sadu, ale nyní existují dvě vstupní sady (p a t). Vzhledem k tomuto omezení musíme explicitně definovat vrácená pole jako name z produktu spolu s velikostmi keya description velikostmi.

Nakonec můžeme pomocí filtru najít velikosti, které končí Large. Vzhledem k tomu, že jsme použili JOIN klíčové slovo, je náš filtr dostatečně flexibilní, aby zvládl libovolný počet proměnných značek:

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

Připojení více položek k sobě

Pojďme přejít k ukázce, kde potřebujeme najít hodnotu v poli, která existuje ve více položkách. V tomto příkladu zvažte kontejner se dvěma položkami produktu. Každá položka obsahuje relevantní colors informace pro danou položku.

[
  {
    "name": "Gremon Fins",
    "colors": [
      "science-blue",
      "turbo"
    ]
  },
  {
    "name": "Elecy Jacket",
    "colors": [
      "indigo-shark",
      "jordy-blue-shark"
    ]
  },
  {
    "name": "Tresko Pack",
    "colors": [
      "golden-dream"
    ]
  }
]

Co když potřebujete najít každou položku s barvou, která obsahuje blue název? Řetězec můžete vyhledat blueručně, ale budete muset napsat složitý dotaz, který odpovídá dvěma vlastnostem těchto položek:

  • Barvy s dílčím řetězcem blue se v jednotlivých polích vyskytují v různých indexech. Elecy Jacket Pro produkt je barva druhou položkou (index: 1). Gremon Fins U produktu je značka první položkou (index: 0). Produkt Tresko Pack neobsahuje žádný podřetětěr.

  • Pole colors pro každou položku má jinou délku. Oba produkty mají dvě barvy, zatímco Tresko Pack produkt má pouze jednu.Gremon FinsElecy Jacket

JOIN Klíčové slovo je skvělým nástrojem pro vytvoření křížového součinu položek a barev. Spojení vytvoří kompletní křížový součin sad, které se účastní spojení. Výsledkem je sada řazených kolekcí členů s každou permutací položky a hodnotami v cílovém poli.

Operace spojení na našich ukázkových produktech a barvách vytvoří následující položky:

Product Barva
Gremon Fins science-blue
Gremon Fins turbo
Elecy Jacket indigo-shark
Elecy Jacket jordy-blue-shark
Tresko Pack golden-dream

Tento příklad dotazu NoSQl používá JOIN klíčové slovo k vytvoření křížového produktu a vrátí všechny permutace:

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

Stejně jako u jedné položky můžete tady použít filtr, abyste našli jenom položky, které odpovídají určité značce. Tento dotaz například najde všechny položky s podřetědcem, který obsahuje blue , aby splňoval počáteční požadavek uvedený výše v této části.

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

Tento dotaz je možné ještě dále upřesnit, aby se vrátily názvy produktů, které splňují filtr. Tento příklad neprojektuje hodnoty barev, ale filtr stále funguje podle očekávání:

SELECT VALUE
  p.name
FROM
  products p
JOIN
  c in p.colors
WHERE
  c LIKE "%blue%"
[
  "Elecy Jacket",
  "Gremon Fins"
]