Gabungan mandiri di Azure Cosmos DB untuk NoSQL

BERLAKU UNTUK: NoSQL

Di Azure Cosmos DB for NoSQL, data bebas skema dan biasanya didenormalisasi. Alih-alih menggabungkan data di seluruh entitas dan set, seperti yang Anda lakukan dalam database relasional, gabungan terjadi dalam satu item. Secara khusus, gabungan dilingkup ke item tersebut dan tidak dapat terjadi di beberapa item dan kontainer.

Tip

Jika Anda merasa perlu bergabung di seluruh item dan kontainer, pertimbangkan untuk mengerjakan ulang model data Anda untuk menghindari hal ini.

Bergabung sendiri dengan satu item

Mari kita lihat contoh gabungan mandiri dalam item. Pertimbangkan kontainer dengan satu item. Item ini mewakili produk dengan berbagai tag:

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

Bagaimana jika Anda perlu menemukan grup warna produk ini? Biasanya, Anda perlu menulis kueri yang memiliki filter yang memeriksa setiap indeks potensial dalam tags array untuk nilai dengan awalan 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-")

Teknik ini bisa menjadi tidak dapat dipertahkan dengan cepat. Kompleksitas atau panjang sintaks kueri meningkatkan jumlah item potensial dalam array. Selain itu, kueri ini tidak cukup fleksibel untuk menangani produk di masa mendatang, yang mungkin memiliki lebih dari tiga tag.

Dalam database relasional tradisional, tag akan dipisahkan menjadi tabel terpisah dan gabungan lintas tabel dilakukan dengan filter yang diterapkan ke hasil. Dalam API untuk NoSQL, kita dapat melakukan operasi gabungan mandiri dalam item menggunakan JOIN kata kunci .

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

Kueri ini mengembalikan array sederhana dengan item untuk setiap nilai dalam array tag.

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

Mari kita uraikan kueri. Kueri sekarang memiliki dua alias: p untuk setiap item produk dalam tataan hasil, dan t untuk array yang digabungkan tags sendiri. Kata * kunci hanya valid untuk memproyeksikan semua bidang jika dapat menyimpulkan set input, tetapi sekarang ada dua set input (p dan t). Karena kendala ini, kita harus secara eksplisit mendefinisikan bidang yang dikembalikan sebagai id dan sku dari produk bersama dengan slug dari tag. Untuk membuat kueri ini lebih mudah dibaca dan dipahami, kita dapat menghilangkan id bidang dan menggunakan alias untuk bidang tag name untuk mengganti namanya menjadi 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"
  }
]

Terakhir, kita dapat menggunakan filter untuk menemukan tag color-group-purple. Karena kami menggunakan JOIN kata kunci , filter kami cukup fleksibel untuk menangani jumlah variabel tag apa pun.

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

Menggabungkan beberapa item secara mandiri

Mari kita lanjutkan ke sampel di mana kita perlu menemukan nilai dalam array yang ada di beberapa item. Untuk contoh ini, pertimbangkan kontainer dengan dua item produk. Setiap item berisi tag yang relevan untuk item tersebut.

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

Bagaimana jika Anda perlu menemukan setiap item dengan bentuk tas mumi ? Anda dapat mencari tag bag-shape-mummy, tetapi Anda perlu menulis kueri kompleks yang memperkirakan dua karakteristik item ini:

  • Tag dengan bag-shape- awalan terjadi pada indeks yang berbeda di setiap array. Untuk kantung tidur Vareno , tag adalah item ketiga (indeks: 2). Untuk kantong tidur Maresse , tag adalah item pertama (indeks: 0).

  • Array tags untuk setiap item memiliki panjang yang berbeda. Tas tidur Vareno memiliki dua tag sementara tas tidur Maresse memiliki tiga.

Di sini, JOIN kata kunci adalah alat yang bagus untuk membuat produk silang dari item dan tag. Gabungan membuat produk silang lengkap dari set yang berpartisipasi dalam gabungan. Hasilnya adalah sekumpulan tuple dengan setiap permutasi item dan nilai dalam array yang ditargetkan.

Operasi gabungan pada sampel produk dan tag kantong tidur kami membuat item berikut:

Item Tag
Tas Tidur Maresse (6') Ming Bentuk Tas: Mummy
Tas Tidur Maresse (6') Ming Isolasi Tas: Isi Bawah
Kantung Tidur Vareno (6') Kunyit Isolasi Tas: Isi Sintetis
Kantung Tidur Vareno (6') Kunyit Grup Warna: Kuning
Kantung Tidur Vareno (6') Kunyit Bentuk Tas: Mummy

Berikut adalah kueri SQL dan hasil JSON yang ditetapkan untuk gabungan yang menyertakan beberapa item dalam kontainer.

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

Sama seperti item tunggal, Anda dapat menerapkan filter di sini untuk menemukan hanya item yang cocok dengan tag tertentu. Misalnya, kueri ini menemukan semua item dengan tag bernama bag-shape-mummy untuk memenuhi persyaratan awal yang disebutkan sebelumnya di bagian ini.

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

Anda juga dapat mengubah filter untuk mendapatkan tataan hasil yang berbeda. Misalnya, kueri ini menemukan semua item yang memiliki tag bernama 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"
  }
]