NoSQL için Azure Cosmos DB'de kendi kendine birleştirmeler

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 düşünüyorsanız, bunu önlemek için veri modelinizi yeniden üzerinde çalışabilirsiniz.

Tek bir öğeyle kendi kendine birleştirme

Ş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": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
    "categoryId": "bbbbbbbb-1111-2222-3333-cccccccccccc",
    "name": "Teapo Surfboard (6'10\") Grape",
    "sku": "teapo-surfboard-72109",
    "tags": [
      {
        "id": "cccccccc-2222-3333-4444-dddddddddddd",
        "slug": "tail-shape-swallow",
        "name": "Tail Shape: Swallow"
      },
      {
        "id": "dddddddd-3333-4444-5555-eeeeeeeeeeee",
        "slug": "length-inches-82",
        "name": "Length: 82 inches"
      },
      {
        "id": "eeeeeeee-4444-5555-6666-ffffffffffff",
        "slug": "color-group-purple",
        "name": "Color Group: Purple"
      }
    ]
  }
]

Bu ürünün renk grubunu bulmanız gerekiyorsa ne yapmanız gerekir? Genellikle, ön ekine color-group-sahip bir değer için dizideki tüm olası dizinleri tags denetleen bir filtre içeren 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şleyecek kadar 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": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
    "sku": "teapo-surfboard-72109",
    "slug": "tail-shape-swallow"
  },
  {
    "id": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
    "sku": "teapo-surfboard-72109",
    "slug": "length-inches-82"
  },
  {
    "id": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb",
    "sku": "teapo-surfboard-72109",
    "slug": "color-group-purple"
  }
]

Şimdi sorguyu bölelim. Sorgunun artık iki diğer adı vardır: p sonuç kümesindeki her ürün öğesi için 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 id name alanı için bir diğer ad kullanarak adını olarak değiştirebiliriz 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şleyebilecek 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ğe geçelim. Bu örnekte, iki ürün öğesi içeren bir kapsayıcı düşünün. Her öğe, bu öğe için uygun etiketler içerir.

[
  {
    "id": "ffffffff-5555-6666-7777-aaaaaaaaaaaa",
    "categoryId": "cccccccc-8888-9999-0000-dddddddddddd",
    "categoryName": "Sleeping Bags",
    "name": "Maresse Sleeping Bag (6') Ming",
    "sku": "maresse-sleeping-bag-65503",
    "tags": [
      {
        "id": "b1b1b1b1-cccc-dddd-eeee-f2f2f2f2f2f2",
        "slug": "bag-shape-mummy",
        "name": "Bag Shape: Mummy"
      },
      {
        "id": "bbbbbbbb-7777-8888-9999-cccccccccccc",
        "slug": "bag-insulation-down-fill",
        "name": "Bag Insulation: Down Fill"
      }
    ]
  },
  {
    "id": "c2c2c2c2-dddd-eeee-ffff-a3a3a3a3a3a3",
    "categoryId": "cccccccc-8888-9999-0000-dddddddddddd",
    "categoryName": "Sleeping Bags",
    "name": "Vareno Sleeping Bag (6') Turmeric",
    "sku": "vareno-sleeping-bag-65508",
    "tags": [
      {
        "id": "dddddddd-9999-0000-1111-eeeeeeeeeeee",
        "slug": "bag-insulation-synthetic-fill",
        "name": "Bag Insulation: Synthetic Fill"
      },
      {
        "id": "a0a0a0a0-bbbb-cccc-dddd-e1e1e1e1e1e1",
        "slug": "color-group-yellow",
        "name": "Color Group: Yellow"
      },
      {
        "id": "b1b1b1b1-cccc-dddd-eeee-f2f2f2f2f2f2",
        "slug": "bag-shape-mummy",
        "name": "Bag Shape: Mummy"
      }
    ]
  }
]

Ya mumya torbası ş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şimler, birleştirmeye katılan kümelerin tam bir çapraz ürünü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 yapılan birleştirme işlemi aşağıdaki öğeleri oluşturur:

Kalem 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 İzolasyonu: 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ümde daha önce bahsedilen 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"
  }
]