الصلات الذاتية في Azure Cosmos DB ل NoSQL
ينطبق على: NoSQL
في Azure Cosmos DB ل NoSQL، تكون البيانات خالية من المخطط وعادة ما يتم إلغاء تنسيقها. بدلا من ضم البيانات عبر الكيانات والمجموعات، كما تفعل في قاعدة بيانات ارتباطية، تحدث الصلات داخل عنصر واحد. على وجه التحديد، يتم تحديد نطاق الصلات لهذا العنصر ولا يمكن أن تحدث عبر عناصر وحاويات متعددة.
تلميح
إذا وجدت نفسك بحاجة إلى الانضمام عبر العناصر والحاويات، ففكر في إعادة صياغة نموذج البيانات لتجنب ذلك.
لنلق نظرة على مثال على الصلة الذاتية داخل عنصر. ضع في اعتبارك حاوية بعنصر واحد. يمثل هذا العنصر منتجا بعلامات مختلفة:
[
{
"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"
}
]
}
]
ماذا لو كنت بحاجة إلى العثور على مجموعة ألوان هذا المنتج؟ عادة ما تحتاج إلى كتابة استعلام يحتوي على عامل تصفية للتحقق من كل فهرس محتمل في tags
الصفيف للحصول على قيمة ببادئة .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-")
يمكن أن تصبح هذه التقنية غير قابلة للتنطاق بسرعة. يزيد تعقيد أو طول بناء جملة الاستعلام من عدد العناصر المحتملة في الصفيف. أيضا، هذا الاستعلام غير مرن بما يكفي للتعامل مع المنتجات المستقبلية، والتي قد تحتوي على أكثر من ثلاث علامات.
في قاعدة بيانات ارتباطية تقليدية، سيتم فصل العلامات إلى جدول منفصل ويتم تنفيذ صلة عبر الجداول مع تطبيق عامل تصفية على النتائج. في واجهة برمجة التطبيقات ل NoSQL، يمكننا إجراء عملية الانضمام الذاتي داخل العنصر باستخدام JOIN
الكلمة الأساسية .
SELECT
p.id,
p.sku,
t.slug
FROM
products p
JOIN
t IN p.tags
يقوم هذا الاستعلام بإرجاع صفيف بسيط مع عنصر لكل قيمة في صفيف العلامات.
[
{
"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"
}
]
دعونا نقسم الاستعلام. يحتوي الاستعلام الآن على اسمين مستعارين: p
لكل عنصر منتج في مجموعة النتائج، والصفيف t
المنضم tags
ذاتيا. *
الكلمة الأساسية صالحة فقط لعرض جميع الحقول إذا كان يمكنها استنتاج مجموعة الإدخال، ولكن هناك الآن مجموعتين من الإدخالات (p
وt
). وبسبب هذا القيد، يجب علينا تحديد الحقول التي تم إرجاعها بشكل صريح ك id
ومن sku
المنتج جنبا إلى جنب مع slug
من العلامات. لتسهيل قراءة هذا الاستعلام وفهمه، يمكننا إسقاط id
الحقل واستخدام اسم مستعار لحقل العلامة name
لإعادة تسميته إلى 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"
}
]
وأخيرا، يمكننا استخدام عامل تصفية للعثور على العلامة color-group-purple
. نظرا لأننا استخدمنا الكلمة الأساسية، فإن عامل التصفية JOIN
لدينا مرن بما يكفي للتعامل مع أي عدد متغير من العلامات.
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"
}
]
لننتقل إلى نموذج حيث نحتاج إلى العثور على قيمة داخل صفيف موجود في عناصر متعددة. على سبيل المثال، ضع في اعتبارك حاوية تحتوي على عنصرين من عناصر المنتج. يحتوي كل عنصر على علامات ذات صلة لهذا العنصر.
[
{
"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"
}
]
}
]
ماذا لو كنت بحاجة إلى العثور على كل عنصر مع شكل حقيبة مومياء ؟ يمكنك البحث عن العلامة bag-shape-mummy
، ولكن ستحتاج إلى كتابة استعلام معقد يمثل خاصيتين لهذه العناصر:
تحدث العلامة
bag-shape-
ذات البادئة في فهارس مختلفة في كل صفيف. بالنسبة إلى حقيبة Vareno السكون، العلامة هي العنصر الثالث (الفهرس:2
). بالنسبة لحقيبة Maresse السكون، العلامة هي العنصر الأول (الفهرس:0
).الصفيف
tags
لكل عنصر طول مختلف. حقيبة Vareno النوم لها علامات اثنين في حين أن حقيبة ماريس النوم لديها ثلاث.
هنا، JOIN
الكلمة الأساسية هي أداة رائعة لإنشاء منتج مشترك للعناصر والعلامات. تنشئ الصلات منتجا متقاطعا كاملا من المجموعات المشاركة في الصلة. والنتيجة هي مجموعة من المجموعات مع كل تباديل للعنصر والقيم داخل الصفيف المستهدف.
تقوم عملية الانضمام على نموذج منتجات وعلامات حقيبة النوم بإنشاء العناصر التالية:
العنصر | العلامة |
---|---|
Maresse Sleeping Bag (6') Ming | شكل حقيبة: مومياء |
Maresse Sleeping Bag (6') Ming | عزل الكيس: تعبئة لأسفل |
Vareno Sleeping Bag (6') الكركم | عزل الكيس: تعبئة اصطناعية |
Vareno Sleeping Bag (6') الكركم | مجموعة الألوان: أصفر |
Vareno Sleeping Bag (6') الكركم | شكل حقيبة: مومياء |
فيما يلي استعلام SQL ومجموعة نتائج JSON لصلة تتضمن عناصر متعددة في الحاوية.
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"
}
]
تماما كما هو الحال مع العنصر الفردي، يمكنك تطبيق عامل تصفية هنا للعثور على العناصر التي تطابق علامة معينة فقط. على سبيل المثال، يبحث هذا الاستعلام عن كافة العناصر ذات العلامة المسماة bag-shape-mummy
لتلبية المتطلبات الأولية المذكورة سابقا في هذا القسم.
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"
}
]
يمكنك أيضا تغيير عامل التصفية للحصول على مجموعة نتائج مختلفة. على سبيل المثال، يبحث هذا الاستعلام عن كافة العناصر التي تحتوي على علامة باسم 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"
}
]