إدارة الفهرسة في Azure Cosmos DB ل MongoDB

ينطبق على: MongoDB

يستفيد Azure Cosmos DB ل MongoDB من قدرات إدارة الفهرس الأساسية ل Azure Cosmos DB. تركز هذه المقالة على كيفية إضافة فهارس باستخدام Azure Cosmos DB ل MongoDB. الفهارس هي هياكل البيانات المتخصصة التي تجعل الاستعلام عن البيانات الخاصة بك تقريباً بصورة أسرع.

الفهرسة لإصدار خادم MongoDB 3.6 وأعلى

يقوم Azure Cosmos DB لخادم MongoDB الإصدار 3.6+ تلقائيا بفهرسة _id الحقل ومفتاح القطع (فقط في المجموعات المقسمة). تفرض واجهة برمجة التطبيقات تلقائياً تفرد الحقل _id لكل مفتاح قطع.

تتصرف واجهة برمجة التطبيقات ل MongoDB بشكل مختلف عن Azure Cosmos DB ل NoSQL، والتي تقوم بفهرسة جميع الحقول بشكل افتراضي.

تحرير نهج الفهرسة

نوصي بتحرير نهج الفهرسة في مستكشف البيانات داخل مدخل Azure. يمكنك إضافة حقل واحد وفهارس البدل من محرر نهج الفهرسة في مستكشف البيانات:

محرر نهج الفهرسة

إشعار

لا يمكنك إنشاء فهارس مركبة باستخدام محرر نهج الفهرسة في مستكشف البيانات.

أنواع الفهارس

حقل منفرد

يمكنك إنشاء فهارس في أي حقل مفرد. لا يهم ترتيب الفرز لفهرس حقل مفرد. يقوم الأمر التالي بإنشاء فهرس في الحقل name:

db.coll.createIndex({name:1})

يمكنك إنشاء نفس فهرس الحقل المفرد على name في مدخل Azure:

إضافة فهرس أسماء في محرر نهج الفهرسة

يستخدم الاستعلام الواحد فهارس متعددة للحقل المفرد حيثما كان ذلك متاحاً. يمكنك إنشاء ما يصل إلى 500 فهرس حقل مفرد لكل مجموعة.

الفهارس المركبة (إصدار خادم MongoDB 3.6+)

في واجهة برمجة التطبيقات لـ MongoDB، تكون الفهارس المركبة مطلوبة إذا كان الاستعلام الخاص بك في حاجة إلى القدرة على الفرز على حقول متعددة في وقت واحد. بالنسبة للاستعلامات التي تحتوي على عوامل تصفية متعددة لا تحتاج إلى الفرز، قم بإنشاء فهارس حقول مفردة متعددة بدلاً من فهرس مركب لتوفير تكاليف الفهرسة.

ينتج عن الفهرس المركب أو فهارس الحقل الواحد لكل حقل في الفهرس المركب نفس الأداء للتصفية في الاستعلامات.

لا يتم دعم الفهارس المركبة في الحقول المتداخلة بشكل افتراضي بسبب القيود مع الصفائف. إذا كان الحقل المتداخل لا يحتوي على صفيف، فإن الفهرس يعمل على النحو المنشود. إذا كان الحقل المتداخل يحتوي على صفيف (في أي مكان على المسار)، يتم تجاهل هذه القيمة في الفهرس.

على سبيل المثال، يعمل فهرس مركب يحتوي على people.dylan.age في هذه الحالة نظرا لعدم وجود صفيف على المسار:

{
  "people": {
    "dylan": {
      "name": "Dylan",
      "age": "25"
    },
    "reed": {
      "name": "Reed",
      "age": "30"
    }
  }
}

لا يعمل نفس الفهرس المركب في هذه الحالة نظرا لوجود صفيف في المسار:

{
  "people": [
    {
      "name": "Dylan",
      "age": "25"
    },
    {
      "name": "Reed",
      "age": "30"
    }
  ]
}

يمكن تمكين هذه الميزة لحساب قاعدة البيانات الخاص بك عن طريق تمكين إمكانية "EnableUniqueCompoundNestedDocs".

إشعار

لا يمكنك إنشاء فهارس مركبة على الصفائف.

يؤدي الأمر التالي إلى إنشاء فهرس مركب على الحقول nameوage:

db.coll.createIndex({name:1,age:1})

يمكنك استخدام الفهارس المركبة للفرز بكفاءة على حقول متعددة في وقت واحد، كما هو موضح في المثال التالي:

db.coll.find().sort({name:1,age:1})

يمكنك أيضاً استخدام الفهرس المركب السابق لفرز أحد الاستعلامات بترتيب عكسي للفرز في جميع الحقول بكفاءة. إليك مثال:

db.coll.find().sort({name:-1,age:-1})

ومع ذلك، يجب أن يتطابق تسلسل المسارات في الفهرس المركب مع الاستعلام تماماً. فيما يلي مثال على استعلام يتطلب فهرس مركب إضافي:

db.coll.find().sort({age:1,name:1})

الفهارس متعددة المفاتيح

يقوم Azure Cosmos DB بإنشاء فهارس متعددة المفاتيح لفهرسة المحتوى المخزن في المصفوفات. إذا قمت بفهرسة حقل بقيمة مصفوفة، يقوم Azure Cosmos DB تلقائياً بفهرسة كل عنصر في المصفوفة.

الفهارس الجغرافية المكانية

سيستفيد العديد من المشغلين الجغرافيين المكانيين من المؤشرات الجغرافية المكانية. حاليا، يدعم 2dsphere Azure Cosmos DB ل MongoDB الفهارس. لا تدعم واجهة برمجة التطبيقات فهارس 2d حتى الآن.

وفيما يلي مثال على إنشاء فهرس جغرافي مكاني في location الحقل:

db.coll.createIndex({ location : "2dsphere" })

فهارس النص

لا يدعم Azure Cosmos DB ل MongoDB حاليا الفهارس النصية. بالنسبة إلى استعلامات البحث النصي على السلاسل، يجب استخدام تكامل Azure الذكاء الاصطناعي Search مع Azure Cosmos DB.

فهارس البدل

يمكنك استخدام فهارس البدل لدعم الاستعلامات لحقول غير معروفة. دعونا نتخيل أن لديك مجموعة تحتوي على بيانات عن العائلات.

هنا جزء من مثال لمستند في تلك المجموعة:

"children": [
   {
     "firstName": "Henriette Thaulow",
     "grade": "5"
   }
]

وهنا مثال آخر، وهذه المرة مع مجموعة مختلفة قليلاً من الخصائص في children:

"children": [
    {
     "familyName": "Merriam",
     "givenName": "Jesse",
     "pets": [
         { "givenName": "Goofy" },
         { "givenName": "Shadow" }
         ]
   },
   {
     "familyName": "Merriam",
     "givenName": "John",
   }
]

في هذه المجموعة، يمكن أن يكون للمستندات العديد من الخصائص الممكنة المختلفة. إذا أردت فهرسة جميع البيانات في المصفوفة children، فلديك خياران: إنشاء فهارس منفصلة لكل خاصية فردية أو إنشاء فهرس بدل واحد للمصفوفة children بأكملها.

إنشاء فهرس أحرف البدل

يقوم الأمر التالي بإنشاء فهرس بدل على أي خصائص داخل children:

db.coll.createIndex({"children.$**" : 1})

خلافاً لما يحدث في MongoDB، يمكن أن تدعم فهارس البدل حقول متعددة في دوال تقييم الاستعلام. لن يكون هناك اختلاف في أداء الاستعلام إذا كنت تستخدم فهرس بدل واحد بدلاً من إنشاء فهرس منفصل لكل خاصية.

يمكنك إنشاء أنواع الفهارس التالية باستخدام بناء جملة البدل:

  • حقل منفرد
  • الجيومكانية

فهرسة جميع الخصائص

إليك كيفية إنشاء فهرس بدل في جميع الحقول:

db.coll.createIndex( { "$**" : 1 } )

يمكنك أيضاً إنشاء فهارس البدل باستخدام مستكشف البيانات في مدخل Azure:

إضافة فهرس البدل في محرر نهج الفهرسة

إشعار

إذا كنت قد بدأت للتو في التطوير، نوصي بشدة بالبدء بفهرس بدل في جميع الحقول. يمكن أن يؤدي ذلك إلى تبسيط التطوير وتسهيل تحسين الاستعلامات.

قد يكون لدى المستندات التي تحتوي على حقول كثيرة رسوم عالية على وحدة الطلبات (RU) للكتابة والتحديثات. ولذلك، إذا كان لديك حمل كتابة مرتفع، يجب أن تختار فهرسة المسارات بشكل فردي بدلاً من استخدام فهارس البدل.

إشعار

يتوفر دعم الفهرس الفريد للمجموعات الموجودة بالبيانات في المعاينة. يمكن تمكين هذه الميزة لحساب قاعدة البيانات الخاص بك عن طريق تمكين إمكانية "EnableUniqueIndexReIndex".

القيود

لا تدعم فهارس البدل أياً من أنواع الفهرس أو الخصائص التالية:

  • مركبة
  • TTL
  • فريد من نوعه

على عكس MongoDB، في Azure Cosmos DB ل MongoDB، لا يمكنك استخدام فهارس البدل ل:

  • إنشاء فهرس بدل يتضمن حقول محددة متعددة

    db.coll.createIndex(
        { "$**" : 1 },
        { "wildcardProjection " :
            {
               "children.givenName" : 1,
               "children.grade" : 1
            }
        }
    )
    
  • إنشاء فهرس بدل يستبعد حقول محددة متعددة

    db.coll.createIndex(
        { "$**" : 1 },
        { "wildcardProjection" :
            {
               "children.givenName" : 0,
               "children.grade" : 0
            }
        }
    )
    

وكبديل، يمكنك إنشاء فهارس بدل متعددة.

خصائص الفهرس

العمليات التالية شائعة للحسابات التي تخدم إصدار البروتوكول السلكي 4.0 والحسابات التي تخدم الإصدارات السابقة. يمكنك معرفة المزيد حول الفهارس المعتمدة والخصائص المفهرسة.

الفهارس المميزة

الفهارس المميزة مفيدة لفرض عدم احتواء مستندين أو أكثر على نفس القيمة للحقول المفهرسة.

يقوم الأمر التالي بإنشاء فهرس مميز في الحقل student_id:

globaldb:PRIMARY> db.coll.createIndex( { "student_id" : 1 }, {unique:true} )
{
    "_t" : "CreateIndexesResponse",
    "ok" : 1,
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 4
}

بالنسبة إلى المجموعات المُقسمة، يجب توفير مفتاح الجزء (القسم) لإنشاء فهرس فريد. بمعنى آخر، جميع الفهارس الفريدة على مجموعة مقسمة هي فهارس مركبة حيث أحد الحقول هو مفتاح القطع. يجب أن يكون الحقل الأول في الترتيب هو مفتاح الجزء.

تقوم الأوامر التالية بإنشاء المجموعة القطعية coll (مفتاح القطع هو university) مع فهرس مميز على الحقول student_id وuniversity:

globaldb:PRIMARY> db.runCommand({shardCollection: db.coll._fullName, key: { university: "hashed"}});
{
    "_t" : "ShardCollectionResponse",
    "ok" : 1,
    "collectionsharded" : "test.coll"
}
globaldb:PRIMARY> db.coll.createIndex( { "university" : 1, "student_id" : 1 }, {unique:true});
{
    "_t" : "CreateIndexesResponse",
    "ok" : 1,
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 3,
    "numIndexesAfter" : 4
}

في المثال السابق، يقوم حذف الجملة "university":1 بإرجاع خطأ تصاحبه الرسالة التالية:

cannot create unique index over {student_id : 1.0} with shard key pattern { university : 1.0 }

القيود

يجب إنشاء فهارس فريدة عندما تكون المجموعة فارغة.

الفهارس الفريدة في الحقول المتداخلة غير معتمدة بشكل افتراضي بسبب القيود مع الصفائف. إذا لم يحتوي الحقل المتداخل على صفيف، فسيعمل الفهرس على النحو المنشود. إذا كان الحقل المتداخل يحتوي على صفيف (في أي مكان على المسار)، تجاهل هذه القيمة في الفهرس الفريد ولن يتم الاحتفاظ بتفرد تلك القيمة.

على سبيل المثال، سيعمل فهرس فريد على people.tom.age في هذه الحالة نظرا لعدم وجود صفيف على المسار:

{ "people": { "tom": { "age": "25" }, "mark": { "age": "30" } } }

ولكن لن يعمل في هذه الحالة نظرا لوجود صفيف في المسار:

{ "people": { "tom": [ { "age": "25" } ], "mark": [ { "age": "30" } ] } }

يمكن تمكين هذه الميزة لحساب قاعدة البيانات الخاص بك عن طريق تمكين إمكانية "EnableUniqueCompoundNestedDocs".

فهارس TTL

لتمكين انتهاء صلاحية المستند في مجموعة معينة، تحتاج إلى إنشاء فهرس (TTL). فهرس TTL هو فهرس في الحقل _ts بقيمة expireAfterSeconds.

مثال:

globaldb:PRIMARY> db.coll.createIndex({"_ts":1}, {expireAfterSeconds: 10})

يحذف الأمر السابق أي مستندات في المجموعة db.coll التي لم يتم تعديلها في آخر 10 ثوان.

إشعار

حقل _ts خاص ب Azure Cosmos DB ولا يمكن الوصول إليه من عملاء MongoDB. وهي خاصية (نظام) محجوزة تحتوي على الطابع الزمني للتعديل الأخير للمستند.

تتبع تقدم الفهرس

الإصدار 3.6+ من Azure Cosmos DB ل MongoDB يدعم currentOp() الأمر لتعقب تقدم الفهرس على مثيل قاعدة بيانات. يقوم هذا الأمر بإرجاع مستند يحتوي على معلومات حول العمليات قيد التقدم على مثيل قاعدة البيانات. يمكنك استخدام الأمر currentOp لتعقب جميع العمليات قيد التقدم في MongoDB الأصلي. في Azure Cosmos DB ل MongoDB، يدعم هذا الأمر فقط تعقب عملية الفهرس.

فيما يلي بعض الأمثلة التي توضح كيفية استخدام الأمر currentOp لتعقب تقدم الفهرس:

  • الحصول على تقدم الفهرس لمجموعة:

    db.currentOp({"command.createIndexes": <collectionName>, "command.$db": <databaseName>})
    
  • الحصول على تقدم الفهرس لجميع المجموعات في قاعدة بيانات:

    db.currentOp({"command.$db": <databaseName>})
    
  • احصل على تقدم الفهرس لجميع قواعد البيانات والمجموعات في حساب Azure Cosmos DB:

    db.currentOp({"command.createIndexes": { $exists : true } })
    

أمثلة على مُخرجات تقدم الفهرس

توضح تفاصيل تقدم الفهرس النسبة المئوية لتقدم عملية الفهرسة الحالية. وفيما يلي مثال يوضح تنسيق مستند المُخرجات لمراحل مختلفة من تقدم الفهرس:

  • سيكون لدي عملية الفهرسة على مجموعة "foo" وقاعدة بيانات "bar" التي تم إكمال 60 بالمائة منها مستند المُخرجات التالي. يظهر الحقل Inprog[0].progress.total 100 كنسبة إكمال الهدف.

    {
          "inprog" : [
          {
                  ………………...
                  "command" : {
                          "createIndexes" : foo
                          "indexes" :[ ],
                          "$db" : bar
                  },
                  "msg" : "Index Build (background) Index Build (background): 60 %",
                  "progress" : {
                          "done" : 60,
                          "total" : 100
                  },
                  …………..…..
          }
          ],
          "ok" : 1
    }
    
  • إذا كانت عملية الفهرسة قد بدأت للتو على مجموعة "foo" وقاعدة بيانات "bar"، فقد يُظهر مستند المُخرجات تقدم 0 بالمائة حتى يصل إلى مستوى قابل للقياس.

    {
          "inprog" : [
          {
                  ………………...
                  "command" : {
                          "createIndexes" : foo
                          "indexes" :[ ],
                          "$db" : bar
                  },
                  "msg" : "Index Build (background) Index Build (background): 0 %",
                  "progress" : {
                          "done" : 0,
                          "total" : 100
                  },
                  …………..…..
          }
          ],
         "ok" : 1
    }
    
  • عند انتهاء عملية الفهرس الحالية، يُظهر مستند المُخرجات العمليات الفارغة لـ inprog.

    {
        "inprog" : [],
        "ok" : 1
    }
    

تحديثات فهرس الخلفية

بغض النظر عن القيمة المحددة لخاصية فهرس الخلفية، يتم تحديث الفهرس دائماً في الخلفية. ونظراً لأن تحديثات الفهرس تستهلك وحدات الطلب (RUs) بأولوية أقل من عمليات قاعدة البيانات الأخرى، فلن تؤدي تغييرات الفهرس إلى أي وقت توقف عن العمل للكتابة أو التحديثات أو الحذف.

لا يوجد أي تأثير لقراءة التوفر عند إضافة فهرس جديد. ستستخدم الاستعلامات الفهارس الجديدة فقط بمجرد اكتمال تحويل الفهرس. وأثناء تحويل الفهرس، سيستمر مشغل الاستعلام في استخدام الفهارس الموجودة، لذلك ستلاحظ أداء قراءة مشابه أثناء تحويل الفهرسة إلى ما لاحظته قبل بدء تغيير الفهرسة. عند إضافة فهارس جديدة، لا يوجد هناك أيضاً أي خطر من ظهور نتائج استعلام غير مكتملة أو غير متناسقة.

عند إزالة الفهارس وتشغيل الاستعلامات التي تحتوي على عوامل تصفية على الفهارس التي تم إسقاطها على الفور، قد تكون النتائج غير متناسقة وغير مكتملة حتى ينتهي تحويل الفهرس. إذا قمت بإزالة الفهارس، فلن يوفر مشغل الاستعلام نتائج متناسقة أو كاملة عند تصفية الاستعلامات على هذه الفهارس التي تمت إزالتها حديثاً. لا يقوم معظم المطورين بإسقاط الفهارس ومحاولة الاستعلام عنها مباشرة بعد ذلك، ففي الممارسة العملية, لا يُحتمل حدوث هذا الوضع.

إشعار

يمكنك تتبع تقدم الفهرس.

أمر إعادة الفهرسة

سيقوم الأمر reIndex بإعادة إنشاء جميع الفهارس على مجموعة. وفي بعض الحالات النادرة، قد يتم حل أداء الاستعلام أو مشاكل الفهرس أخرى في مجموعتك عن طريق تشغيل الأمر reIndex. إذا كنت تواجه مشكلات في الفهرسة، يُستحسن إعادة إنشاء الفهارس باستخدام الأمر reIndex.

يمكنك تشغيل الأمر reIndex باستخدام بناء الجملة التالي:

db.runCommand({ reIndex: <collection> })

يمكنك استخدام بناء الجملة أدناه للتحقق مما إذا كان تشغيل الأمر reIndex سيؤدي إلى تحسين أداء الاستعلام في المجموعة:

db.runCommand({"customAction":"GetCollection",collection:<collection>, showIndexes:true})

عينة الإخراج:

{
        "database" : "myDB",
        "collection" : "myCollection",
        "provisionedThroughput" : 400,
        "indexes" : [
                {
                        "v" : 1,
                        "key" : {
                                "_id" : 1
                        },
                        "name" : "_id_",
                        "ns" : "myDB.myCollection",
                        "requiresReIndex" : true
                },
                {
                        "v" : 1,
                        "key" : {
                                "b.$**" : 1
                        },
                        "name" : "b.$**_1",
                        "ns" : "myDB.myCollection",
                        "requiresReIndex" : true
                }
        ],
        "ok" : 1
}

إذا كان reIndex سيقوم بتحسين أداء الاستعلام، requiresReIndex فسيكون صحيحاً. وإذا لم يحسن reIndex أداء الاستعلام، فسيتم حذف هذه الخاصية.

ترحيل المجموعات ذات الفهارس

حالياً، يمكنك فقط إنشاء فهارس مميزة عندما لا تحتوي المجموعة على مستندات. تحاول أدوات الترحيل المنتشرة في MongoDB خلق فهارس مميزة من نوعها بعد استيراد البيانات. وللتحايل على هذه المشكلة، يمكنك إنشاء المجموعات المطابقة والفهارس المميزة يدوياً بدلاً من السماح لأداة الترحيل بالمحاولة. (يمكنك تحقيق هذا السلوك لـ mongorestore باستخدام العلامة --noIndexRestore في سطر الأوامر).

فهرسة الإصدار MongoDB 3.2

تختلف ميزات الفهرسة والإعدادات الافتراضية المتوفرة لحسابات Azure Cosmos DB المتوافقة مع الإصدار 3.2 من بروتوكول MongoDB السلكي. يمكنك التحقق من إصدار حسابك والترقية إلى الإصدار 3.6.

إذا كنت تستخدم الإصدار 3.2، يوضح هذا القسم الاختلافات الرئيسة مع الإصدارات 3.6+.

إسقاط الفهارس الافتراضية (الإصدار 3.2)

على عكس الإصدارات 3.6+ من Azure Cosmos DB ل MongoDB، يقوم الإصدار 3.2 بفهرسة كل خاصية بشكل افتراضي. يمكنك استخدام الأمر التالي لإسقاط هذه الفهارس الافتراضية لمجموعة (coll):

> db.coll.dropIndexes()
{ "_t" : "DropIndexesResponse", "ok" : 1, "nIndexesWas" : 3 }

بعد إسقاط الفهارس الافتراضية، يمكنك إضافة المزيد من الفهارس كما تفعل في الإصدار 3.6+.

الفهارس المركبة (الإصدار 3.2)

لدي الفهارس المركبة مراجع إلى حقول متعددة من المستند. إذا كنت ترغب في إنشاء فهرس مركب، فقم بـ الترقية إلى الإصدار 3.6 أو 4.0.

فهارس البدل (الإصدار 3.2)

إذا كنت ترغب في إنشاء فهرس البدل، فقم بـ الترقية إلى الإصدار 4.0 أو 3.6.

الخطوات التالية