Öncsatlakozások az Azure Cosmos DB for NoSQL-ben

A KÖVETKEZŐRE VONATKOZIK: NoSQL

Az Azure Cosmos DB for NoSQL-ben az adatok sémamentesek és általában denormalizáltak. Ahelyett, hogy az adatokat entitások és készletek között illesztené össze, például egy relációs adatbázisban, az illesztések egyetlen elemen belül történnek. Az illesztések hatóköre az adott elemre terjed ki, és nem fordulhat elő több elem és tároló között.

Tipp

Ha úgy találja, hogy elemekhez és tárolókhoz kell csatlakoznia, érdemes lehet átdolgozni az adatmodellt ennek elkerülése érdekében.

Önálló illesztés egyetlen elemtel

Tekintsünk meg egy példát egy elemen belüli önillesztésre. Fontolja meg egy egyetlen elemből álló tárolót. Ez az elem egy különböző címkével rendelkező terméket jelöl:

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

Mi a teendő, ha meg kell találnia a termék színcsoportját ? Általában olyan lekérdezést kell írnia, amely egy szűrővel ellenőrzi a tags tömb minden lehetséges indexét egy olyan értékhez, amelynek előtagja 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-")

Ez a technika gyorsan elérhetetlenné válhat. A lekérdezési szintaxis összetettsége vagy hossza megnöveli a tömb lehetséges elemeinek számát. Emellett ez a lekérdezés nem elég rugalmas a jövőbeli termékek kezeléséhez, amelyek háromnál több címkével rendelkezhetnek.

Egy hagyományos relációs adatbázisban a címkék külön táblára lesznek osztva, és egy táblaközi illesztést hajtanak végre az eredményekre alkalmazott szűrővel. A NoSQL API-ban öncsatlakozási műveletet hajthatunk végre az elemen belül a JOIN kulcsszó használatával.

SELECT
  p.id,
  p.sku,
  t.slug
FROM
  products p
JOIN
  t IN p.tags

Ez a lekérdezés egy egyszerű tömböt ad vissza, amely a címkék tömbjének minden értékéhez tartalmaz egy elemet.

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

Bontsuk le a lekérdezést. A lekérdezésnek most két aliasa van: p az eredményhalmaz minden termékeleméhez és t az önkiszolgáló tags tömbhöz. A * kulcsszó csak akkor érvényes az összes mező kivetítésére, ha ki tudja következtetni a bemeneti készletet, de most két bemeneti készlet van (p és t). A kényszer miatt explicit módon meg kell határoznunk a visszaadott mezőket a termék slug és idsku a címkék között. A lekérdezés olvashatóbbá és érthetőbbé tétele érdekében elvethetjük a id mezőt, és aliast használhatunk a címke mezőihez name , hogy átnevezzük a névre 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"
  }
]

Végül egy szűrővel megkereshetjük a címkét color-group-purple. Mivel a kulcsszót JOIN használtuk, a szűrő elég rugalmas ahhoz, hogy bármilyen változó számú címkét kezeljen.

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

Több elem önálló összekapcsolása

Térjünk át egy olyan mintára, amelyben meg kell találnunk egy értéket egy tömbben, amely több elemet tartalmaz. Ebben a példában egy két termékelemet tartalmazó tárolót érdemes figyelembe venni. Minden elem az adott elemhez kapcsolódó címkéket tartalmaz.

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

Mi van, ha meg kell találni minden elem egy múmia táska alakú? Megkeresheti a címkét bag-shape-mummy, de egy összetett lekérdezést kell írnia, amely ezeknek az elemeknek a két jellemzőjét adja:

  • Az előtaggal rendelkező bag-shape- címke az egyes tömbök különböző indexeiben fordul elő. A Vareno hálózsák esetében a címke a harmadik elem (index: 2). A Maresse hálózsák esetében a címke az első elem (index: 0).

  • Az tags egyes elemek tömbje eltérő hosszúságú. A Vareno hálózsák két címkét, míg a Maresse hálózsák három.

Itt a JOIN kulcsszó egy nagyszerű eszköz az elemek és címkék kereszttermékének létrehozásához. Az illesztések az illesztésben részt vevő készletek teljes kereszttermékét hozzák létre. Az eredmény az elemek és a megcélzott tömb értékeinek minden permutációjával rendelkező rekordok halmaza.

A hálózsák-mintatermékek és -címkék illesztési művelete a következő elemeket hozza létre:

Elem Címke
Maresse hálózsák (6') Ming Táska alakja: múmia
Maresse hálózsák (6') Ming Táska szigetelése: letöltő
Vareno hálózsák (6') Kurkuma Táska szigetelése: Szintetikus kitöltés
Vareno hálózsák (6') Kurkuma Színcsoport: sárga
Vareno hálózsák (6') Kurkuma Táska alakja: múmia

Íme az SQL-lekérdezés és a JSON-eredménykészlet egy olyan illesztéshez, amely több elemet tartalmaz a tárolóban.

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

Az egyetlen elemhez hasonlóan itt is alkalmazhat szűrőt, hogy csak azokat az elemeket keresse meg, amelyek megfelelnek egy adott címkének. Ez a lekérdezés például megkeresi az összes olyan elemet, amelynek neve egy címkével bag-shape-mummy rendelkezik, hogy megfeleljen az ebben a szakaszban korábban említett kezdeti követelménynek.

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

A szűrőt úgy is módosíthatja, hogy egy másik eredményhalmazt kapjon. Ez a lekérdezés például az összes olyan elemet megkeresi, amely a nevű címkével rendelkezik 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"
  }
]