NoSQL için Azure Cosmos DB'de kendi kendine katılmalar

UYGULANANLAR: NOSQL

NoSQL için Azure Cosmos DB'de veriler şemasızdır ve normalde normal dışıdır. İlişkisel veritabanında yaptığınız gibi varlıklar ve kümeler arasında verileri birleştirmek yerine birleştirmeler tek bir öğe içinde gerçekleşir. Özellikle birleşimlerin kapsamı bu öğeye göre belirlenmiştir ve birden çok öğe ve kapsayıcıda gerçekleşemez.

İpucu

Öğeler ve kapsayıcılar arasında katılmanız gerektiğini fark ederseniz, bunu önlemek için veri modelinizde yeniden çalışma yapmayı göz önünde bulundurun.

Tek bir öğeyle kendi kendine katılma

Şimdi bir öğe içinde kendi kendine birleştirme örneğine bakalım. Tek öğeli bir kapsayıcı düşünün. Bu öğe, çeşitli etiketlere sahip bir ürünü temsil eder:

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

Bu ürünün renk grubunu bulmanız gerekirse ne olur? Genellikle, dizideki tüm olası dizinlerde tags ön ekine color-group-sahip bir değer için filtre denetimi olan bir sorgu yazmanız gerekir.

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-")

Bu teknik hızlı bir şekilde engellenemez hale gelebilir. Sorgu söz diziminin karmaşıklığı veya uzunluğu dizideki olası öğelerin sayısını artırır. Ayrıca bu sorgu, üçten fazla etikete sahip olabilecek gelecek ürünleri işlemek için yeterince esnek değildir.

Geleneksel bir ilişkisel veritabanında etiketler ayrı bir tabloya ayrılır ve sonuçlara uygulanan bir filtre ile tablolar arası birleştirme gerçekleştirilir. NoSQL API'sinde, anahtar sözcüğünü JOIN kullanarak öğenin içinde kendi kendine birleştirme işlemi gerçekleştirebiliriz.

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

Bu sorgu, etiketler dizisindeki her değer için bir öğe içeren basit bir dizi döndürür.

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

Şimdi sorguyu ayıralım. Sorgunun artık iki diğer adı vardır: p sonuç kümesindeki her ürün öğesi ve t kendi kendine birleştirilen tags dizi için. Anahtar * sözcüğü yalnızca giriş kümesini çıkarsayabiliyorsa tüm alanları yansıtmak için geçerlidir, ancak şimdi iki giriş kümesi (p ve t) vardır. Bu kısıtlama nedeniyle, döndürülen alanlarımızı etiketlerle slug birlikte ürün olarak ve sku üründen açıkça id tanımlamamız gerekir. Bu sorgunun okunmasını ve anlaşılmasını kolaylaştırmak için alanını bırakabilir ve etiketin idname alanının diğer adını kullanarak olarak yeniden adlandırabiliriz 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"
  }
]

Son olarak, etiketini color-group-purplebulmak için bir filtre kullanabiliriz. Anahtar sözcüğünü kullandığımızdan JOIN , filtremiz değişken sayıda etiketi işleyecek kadar esnektir.

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

Birden çok öğeyi kendi kendine birleştirme

Şimdi birden çok öğede bulunan bir dizi içinde bir değer bulmamız gereken bir örne geçelim. Bu örnekte, iki ürün öğesi içeren bir kapsayıcıyı göz önünde bulundurun. Her öğe, bu öğe için uygun etiketler içerir.

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

Ya mumya çantası şeklindeki her öğeyi bulman gerekirse? etiketini bag-shape-mummyarayabilirsiniz, ancak bu öğelerin iki özelliğini hesaplayan karmaşık bir sorgu yazmanız gerekir:

  • Ön eki olan bag-shape- etiket her dizideki farklı dizinlerde gerçekleşir. Vareno uyku tulumu için etiket üçüncü öğedir (dizin: 2). Maresse uyku tulumu için etiket ilk öğedir (dizin: 0).

  • tags Her öğenin dizisi farklı bir uzunluktadır. Vareno uyku tulumunun iki etiketi, Maresse uyku tulumunun üç etiketi vardır.

Burada anahtar sözcük, JOIN öğelerin ve etiketlerin çapraz çarpımını oluşturmak için harika bir araçtır. Birleştirmeler, birleştirmeye katılan kümelerin eksiksiz bir çapraz çarpımını oluşturur. Sonuç, öğenin her permütasyonunu ve hedeflenen dizideki değerleri içeren bir demet kümesidir.

Örnek uyku tulumu ürünlerimizde ve etiketlerimizde bir birleştirme işlemi aşağıdaki öğeleri oluşturur:

Öğe Etiket
Maresse Uyku Tulumu (6') Ming Çanta Şekli: Mumya
Maresse Uyku Tulumu (6') Ming Torba Yalıtımı: Aşağı Dolgu
Vareno Uyku Tulumu (6') Zerdeçal Torba Yalıtımı: Sentetik Dolgu
Vareno Uyku Tulumu (6') Zerdeçal Renk Grubu: Sarı
Vareno Uyku Tulumu (6') Zerdeçal Çanta Şekli: Mumya

Kapsayıcıda birden çok öğe içeren bir birleştirme için SQL sorgusu ve JSON sonuç kümesi aşağıdadır.

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

Tek öğede olduğu gibi, yalnızca belirli bir etiketle eşleşen öğeleri bulmak için buraya filtre uygulayabilirsiniz. Örneğin, bu sorgu, bu bölümün önceki bölümlerinde belirtilen ilk gereksinimi karşılamak için adlı bag-shape-mummy etikete sahip tüm öğeleri bulur.

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

Farklı bir sonuç kümesi almak için filtreyi de değiştirebilirsiniz. Örneğin, bu sorgu adlı bag-insulation-synthetic-filletiketi olan tüm öğeleri bulur.

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