إضافة Firestore Vector Search إلى تطبيقاتك المتوافقة مع الأجهزة الجوّالة باستخدام إضافات Firebase

1- نظرة عامة

في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كيفية إضافة ميزات بحث فعّالة إلى تطبيقك باستخدام ميزة البحث عن تشابه المتّجهات من Firestore. ستنفِّذ ميزة البحث الدلالي لتطبيق تدوين ملاحظات مكتوب بلغتَي Swift وSwiftUI.

وحدة تحكّم Cloud Firestore تعرض بعض المستندات التي تظهر أيضًا في تطبيق iOS على الجانب الأيمن

ما سوف تتعلمه

  • كيفية تثبيت إضافة Vector Search with Firestore لحساب تضمينات المتجهات.
  • كيفية استدعاء وظائف Firebase Cloud من تطبيق Swift
  • كيفية فلترة البيانات مسبقًا استنادًا إلى المستخدم الذي سجّل الدخول

ما ستحتاجه

  • Xcode 15.3
  • تمثّل هذه السمة رمز نموذجي حول الترميز. وسيتم تنزيل هذا الملف في خطوة لاحقة من ورشة رموز البرامج.

2- إنشاء مشروع على Firebase وإعداده

لاستخدام إضافة بحث فاكتور من Firebase، ستحتاج إلى مشروع في Firebase. في هذا الجزء من ورشة رموز البرامج، ستنشئ مشروعًا جديدًا على Firebase وتفعّل الخدمات المطلوبة، مثل Cloud Firestore وFirebase Authentication.

إنشاء مشروع على Firebase

  1. سجِّل الدخول إلى Firebase.
  2. في "وحدة تحكّم Firebase"، انقر على إضافة مشروع، ثمّ أدخِل اسمًا لمشروعك هو Firestore Vector Search Labإنشاء مشروع، الخطوة 1 من 3: اختيار اسم المشروع.
  3. انقر على خيارات إنشاء المشروع. اقبل بنود Firebase إذا طُلب منك ذلك.
  4. في شاشة "إحصاءات Google"، أزِل العلامة من المربّع تفعيل "إحصاءات Google" لهذا المشروع، لأنّك لن تستخدم "إحصاءات Google" لهذا التطبيق.
  5. أخيرًا، انقر على إنشاء مشروع.

لمزيد من المعلومات عن مشاريع Firebase، يُرجى الاطّلاع على مقالة فهم مشاريع Firebase.

ترقية خطة أسعار Firebase

لاستخدام "إضافات Firebase" وخدمات السحابة الإلكترونية الأساسية، يجب أن يكون مشروعك على Firebase مُدرَجًا في خطة الأسعار "الدفع حسب الاستخدام" (Blaze)، ما يعني أنّه مرتبط بحساب على Cloud Billing.

  • يتطلّب حساب "الفوترة في Google Cloud" طريقة دفع، مثل بطاقة الائتمان.
  • إذا كنت مستخدمًا جديدًا لمنصة Firebase وGoogle Cloud، يُرجى التحقّق من أهليتك للحصول على رصيد بقيمة 300 دولار أمريكي وحساب فوترة تجريبي مجاني على Cloud.
  • إذا كنت تشارك في هذا الإصدار التجريبي من رمز المصدر كجزء من حدث، اسأل المنظِّم ما إذا كانت هناك أي أرصدة متاحة في Cloud.

لترقية مشروعك إلى خطة Blaze، اتّبِع الخطوات التالية:

  1. في "وحدة تحكّم Firebase"، اختَر ترقية خطتك.
  2. اختَر خطة Blaze. اتّبِع التعليمات الظاهرة على الشاشة لربط حساب "فوترة على Cloud" بمشروعك.
    إذا كنت بحاجة إلى إنشاء حساب "فوترة على Cloud" كجزء من هذه الترقية، قد تحتاج إلى الرجوع إلى مسار الترقية في وحدة تحكّم Firebase لإكمال الترقية.

تفعيل منتجات Firebase وإعدادها في وحدة التحكّم

يستخدم التطبيق الذي تنشئه العديد من منتجات Firebase المتاحة لتطبيقات Apple:

  • مصادقة Firebase للسماح للمستخدمين بتسجيل الدخول إلى تطبيقك بسهولة
  • Cloud Firestore لحفظ البيانات المنظَّمة في السحابة الإلكترونية والحصول على إشعار فوري عند تغيُّر البيانات
  • قواعد أمان Firebase لتأمين قاعدة البيانات.

وتتطلّب بعض هذه المنتجات إعدادًا خاصًا أو تفعيلها باستخدام وحدة تحكُّم Firebase.

تفعيل المصادقة المجهولة لمصادقة Firebase

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

  1. في اللوحة اليمنى من وحدة تحكّم Firebase، انقر على الإنشاء > المصادقة. بعد ذلك، انقر على البدء.تفعيل ميزة "المصادقة على Firebase"
  2. لقد انتقلت الآن إلى لوحة بيانات المصادقة، حيث يمكنك الاطّلاع على المستخدمين الذين سجّلوا الدخول وضبط مقدّمي خدمات تسجيل الدخول وإدارة الإعدادات.
  3. انقر على علامة التبويب طريقة تسجيل الدخول (أو انقر على هذا الرابط للانتقال مباشرةً إلى علامة التبويب).
  4. انقر على مجهول من خيارات مقدّم الخدمة، وبدِّل مفتاح التبديل إلى تفعيل، ثمّ انقر على حفظ.

إعداد Cloud Firestore

يستخدم تطبيق Swift هذا Cloud Firestore لحفظ الملاحظات.

في ما يلي كيفية إعداد Cloud Firestore في مشروعك على Firebase:

  1. في اللوحة اليمنى من "وحدة تحكّم Firebase"، وسِّع الإنشاء، ثم اختَر قاعدة بيانات Firestore.
  2. انقر على إنشاء قاعدة بيانات.
  3. اترك معرّف قاعدة البيانات مضبوطًا على (default).
  4. اختَر موقعًا لقاعدة بياناتك، ثم انقر على التالي.
    بالنسبة إلى التطبيق الحقيقي، عليك اختيار موقع قريب من المستخدمين.
  5. انقر على البدء في وضع الاختبار. اقرأ بيان إخلاء المسؤولية بشأن قواعد الأمان.
    في وقت لاحق من هذا الدليل التعليمي، ستضيف قواعد أمان لتأمين بياناتك. لا توزِّع تطبيقًا أو تعرضه علنًا بدون إضافة قواعد أمان لقاعدة البيانات.
  6. انقر على إنشاء.

إعداد خدمة Cloud Storage لمنصّة Firebase

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

في ما يلي كيفية إعداد ميزة "التخزين في السحابة الإلكترونية" لبرنامج Firebase في مشروعك على Firebase:

  1. في اللوحة اليمنى من وحدة تحكّم Firebase، وسِّع الإصدار، ثم اختَر مساحة التخزين.
  2. انقر على البدء.
  3. اختَر موقعًا جغرافيًا لحزمتك التلقائية على مساحة التخزين.
    يمكن للحِزم في US-WEST1 وUS-CENTRAL1 وUS-EAST1 الاستفادة من المستوى "المجاني دائمًا" في Google Cloud Storage. تخضع الحِزم في جميع المواقع الجغرافية الأخرى لأسعار Google Cloud Storage واستخدامها.
  4. انقر على البدء في وضع الاختبار. اقرأ بيان إخلاء المسؤولية بشأن قواعد الأمان.
    في وقت لاحق من هذا الدليل التعليمي، ستضيف قواعد أمان لتأمين بياناتك. لا توزِّع تطبيقًا علنًا أو تعرضه بدون إضافة قواعد أمان لحزمة التخزين.
  5. انقر على إنشاء.

3- ربط تطبيق الأجهزة الجوّالة

في هذا القسم من ورشة رموز البرامج، ستنزِّل رمز المصدر لتطبيق بسيط لتدوين الملاحظات، وتربطه بمشروع Firebase الذي أنشأته للتو.

تنزيل نموذج التطبيق

  1. انتقِل إلى https://github.com/FirebaseExtended/codelab-firestore-vectorsearch-ios، وانسخ المستودع إلى جهازك المحلي
  2. افتح مشروع Notes.xcodeproj في Xcode.

ربط التطبيق بمشروعك على Firebase

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

لمزيد من المعلومات عن مشاريع Firebase، يُرجى الاطّلاع على مقالة فهم مشاريع Firebase.

  1. في "وحدة تحكُّم Firebase"، انتقِل إلى صفحة النظرة العامة على مشروعك على Firebase.صفحة النظرة العامة على "وحدة تحكُّم Firebase"
  2. انقر على رمز iOS+ لإضافة تطبيق iOS.
  3. في شاشة إضافة Firebase إلى تطبيق Apple، أدخِل معرّف الحزمة من مشروع Xcode (com.google.firebase.codelab.Notes).
  4. يمكنك إدخال اسم مختصر للتطبيق إذا أردت (ملاحظات حول أجهزة iOS).
  5. انقر على "تسجيل التطبيق" للانتقال إلى الخطوة التالية.
  6. نزِّل ملف GoogleServices-Info.plist.
  7. اسحب GoogleServices-Info.plist إلى مجلد Notes في مشروع Xcode. من الطرق الجيدة لإجراء ذلك إسقاطه أسفل ملف Assets.xcassets.سحب ملف plist إلى Xcode
  8. اختَر نسخ العناصر إذا لزم الأمر، وتأكَّد من اختيار المستهدَف الملاحظات في الإضافة إلى الاستهدافات، ثم انقر على إنهاء.اختيار "النسخ إذا لزم الأمر" في مربّع الحوار "اختيار خيارات إضافة الملفات"
  9. في وحدة تحكّم Firebase، يمكنك الآن النقر على باقي خطوات عملية الإعداد: تم تثبيت حزمة تطوير البرامج (SDK) لمنصّة Apple من Firebase في العيّنة التي نزّلتها في بداية هذا القسم، وتم إعداد عملية الإعداد الأولي. يمكنك إنهاء العملية من خلال النقر على متابعة إلى وحدة التحكّم.

تشغيل التطبيق

حان الوقت الآن لتجربة التطبيق!

  1. في Xcode، شغِّل التطبيق على "محاكي iOS". في القائمة المنسدلة تشغيل وجهات التشغيل، اختَر أولاً إحدى محاكيات iOS.اختيار محاكي iOS في القائمة المنسدلة "الوجهات التي سيتم تشغيلها"
  2. بعد ذلك، انقر على الزر تشغيل أو اضغط على ⌘ + R
  3. بعد تشغيل التطبيق بنجاح على المحاكي، أضِف بضع ملاحظات.
  4. في وحدة تحكُّم Firebase، انتقِل إلى متصفّح بيانات Firestore حتى تتمكّن من الاطّلاع على المستندات الجديدة التي يتم إنشاؤها عند إضافة ملاحظات جديدة في التطبيق.وحدة تحكم Cloud Firestore تعرض بعض المستندات، إلى جانب مُحاكي iOS الذي يعرض المستندات نفسها

4. تثبيت Vector Search باستخدام إضافة Firestore

في هذا الجزء من "مختبر الرموز البرمجية"، ستثبِّت إضافة "البحث المرئي" باستخدام Firestore، وسيتم ضبطها وفقًا لمتطلبات تطبيق تدوين الملاحظات الذي تعمل عليه.

بدء تثبيت الإضافة

  1. في قسم Firestore، انقر على علامة التبويب الإضافات.اختيار علامة التبويب "إضافات Firebase" في وحدة تحكُّم Firestore
  2. انقر على استكشاف مركز الإضافات.علامة التبويب "إضافات Firebase" في وحدة تحكُّم Firestore
  3. اكتب كلمة "متجه".
  4. انقر على "بحث متجه باستخدام إضافة Firestore".الصفحة المقصودة لخدمة Firebase Extensios Hub سينقلك هذا الإجراء إلى صفحة تفاصيل الإضافة، حيث يمكنك الاطّلاع على مزيد من المعلومات عن الإضافة وطريقة عملها وخدمات Firebase التي تتطلّبها وكيفية ضبطها.
  5. انقر على التثبيت في وحدة تحكُّم Firebase.زر التثبيت لإضافة "البحث باستخدام الأشكال الهندسية" مع Firestore
  6. ستظهر لك قائمة بجميع مشاريعك.
  7. اختَر المشروع الذي أنشأته في الخطوة الأولى من هذا الدرس التطبيقي.شاشة أداة اختيار مشروع Firebase

ضبط الإضافة

  1. راجِع واجهات برمجة التطبيقات المفعَّلة والموارد التي تم إنشاؤها.مراجعة واجهات برمجة التطبيقات المفعَّلة
  2. يجب تفعيل الخدمات المطلوبة.تفعيل الخدمات المطلوبة
  3. بعد تفعيل جميع الخدمات، انقر على التالي.انقر على "التالي" بعد تفعيل جميع الخدمات.
  4. راجِع الأذونات الممنوحة لهذه الإضافة.
  5. ضبط الإضافة:
    • اختَر Vertex AI كـ النموذج اللغوي الكبير.
    • مسار المجموعة: notes
    • الحدّ الأقصى التلقائي لطلبات البحث: 3
    • اسم حقل الإدخال: text
    • اسم حقل الإخراج: embedding
    • اسم حقل الحالة:* *status*
    • تضمين المستندات الحالية: نعم
    • تعديل المستندات الحالية: نعم
    • موقع Cloud Function: us-central1
  6. انقر على تثبيت الإضافة لإكمال عملية التثبيت.

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

5- الخلفية

أثناء انتظار اكتمال عملية التثبيت، إليك بعض المعلومات الأساسية حول آلية عمل إضافة "البحث المرئي" مع Firestore.

ما هي المتجهات والعناصر المضمّنة وقواعد بيانات المتجهات؟

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

كيف تعمل ميزة "البحث بالاستناد إلى الرسومات"؟

تعمل ميزة "البحث باستخدام المتجهات" من خلال مقارنة متجه طلب البحث بجميع المتجهات في قاعدة البيانات. يتم عرض المتجهات الأكثر تشابهًا مع متجه الطلب كنتائج البحث.

يمكن قياس التشابه بين متجهَين باستخدام مجموعة متنوعة من مقاييس المسافة. إنّ مقياس المسافة الأكثر شيوعًا هو تشابه جيب التمام الذي يقيس الزاوية بين متجهَين.

6- تجربة إضافة "البحث باستخدام المتجهات" مع Firestore

قبل استخدام إضافة "البحث المرئي" مع Firestore في تطبيق iOS الذي نزّلته سابقًا في هذا الدليل التعليمي حول رموز البرامج، يمكنك تجربة الإضافة في وحدة تحكّم Firebase.

قراءة المستندات

تتضمّن إضافات Firebase مستندات حول آلية عملها.

  1. بعد انتهاء تثبيت الإضافة، انقر على الزر البدء. صفحة النظرة العامة على إضافة Firebase في وحدة تحكُّم Firebase
  2. راجع علامة التبويب "كيفية عمل هذه الإضافة" وهي تشرح ما يلي:
    • كيفية احتساب عمليات التضمين للمستندات من خلال إضافتها إلى مجموعة notes
    • كيفية إجراء طلب بحث في الفهرس من خلال استدعاء الدالة القابلة للاستدعاء ext-firestore-vector-search-queryCallable
    • أو كيفية الاستعلام عن الفهرس من خلال إضافة مستند طلب بحث إلى مجموعة _firestore-vector-search/index/queries.
    • ويوضّح أيضًا كيفية إعداد دالة تضمين مخصّصة، وهو أمر مفيد إذا لم تستوفِ أي من النماذج اللغوية الكبيرة المتوافقة مع الإضافة متطلباتك، وأردت استخدام نموذج لغوي كبير مختلف لاحتساب عمليات الدمج. مستندات إضافة "البحث باستخدام المتجهات" مع Firestore
  3. انقر على رابط لوحة بيانات Cloud Firestore للانتقال إلى نسختك من Firestore.
  4. انتقِل إلى مستند _firestore-vector-search/index. من المفترض أن يُظهر ذلك أنّ الإضافة قد أكملت احتساب عمليات التضمين لجميع مستندات الملاحظات التي أنشأتها في خطوة سابقة في هذا الدليل التعليمي.إعداد الفهرس داخل وحدة تحكّم Firestore
  5. للتأكّد من ذلك، افتح أحد مستندات الملاحظات، ومن المفترض أن يظهر لك حقل إضافي باسم embedding من النوع vector<768>، بالإضافة إلى حقل status.حقل إدراج متّجه داخل وحدة تحكّم Firestore

إنشاء نموذج مستند

يمكنك إنشاء مستند جديد في "وحدة تحكُّم Firebase" للاطّلاع على الإضافة عمليًا.

  1. لا تزال في متصفّح بيانات Firestore، انتقِل إلى مجموعة notes وانقر على + إضافة مستند في العمود الأوسط.إضافة مستند جديد
  2. انقر على المعرّف التلقائي لإنشاء معرّف مستند فريد جديد.
  3. أضِف حقلًا باسم text من النوع سلسلة، والصِق بعض النصوص في حقل القيمة. من المهم ألا يكون هذا lorem ipsum أو أي نص عشوائي آخر. اختَر مقالة إخبارية، على سبيل المثال.إضافة حقل نصي
  4. انقر على حفظ.
    • لاحظ كيف تضيف الإضافة حقل حالة للإشارة إلى أنّها تعالج البيانات.
    • بعد فترة قصيرة، من المفترض أن يظهر لك حقل جديد embedding بقيمة vector<768>.
    تعديل حالة عمليات تضمين الخط المتجه في المستند الجديد

إجراء طلب بحث

تتضمّن إضافة "البحث باستخدام المتجهات" مع Firestore ميزة صغيرة رائعة تتيح لك البحث في فهرس المستندات بدون الحاجة إلى ربط تطبيق.

  1. في قسم Firestore ضمن وحدة تحكّم Firebase، انتقِل إلى مستند _firestore-vector-search/index.
  2. انقر على + بدء مجموعةإضافة مجموعة فرعية جديدة.
  3. أنشئ مجموعة فرعية جديدة باسم queries.
  4. أنشئ مستندًا جديدًا واضبط الحقل query على نص يظهر في أحد مستنداتك. يعمل هذا الإجراء بشكل أفضل مع طلبات البحث الدلالية، مثل "كيف يمكنني ربط مستندات Firestore باستخدام Swift" (شرط أن تحتوي ملاحظة واحدة على الأقل من الملاحظات التي أضفتها على نص يتناول هذا الموضوع).إضافة حقل استعلام
  5. قد تظهر لك رسالة خطأ في حالة التطبيقحدث خطأ
  6. ويعود السبب في ذلك إلى عدم توفّر فهرس. لإعداد إعدادات الفهرس المفقودة، انتقِل إلى وحدة تحكّم Google Cloud لمشروعك باتّباع هذا الرابط، ثم اختَر مشروعك من القائمة.اختيار المشروع الصحيح
  7. في "مستكشف سجلّات Cloud"، من المفترض أن تظهر الآن رسالة خطأ تفيد بأنّ "FAILED_PRECONDITION: Missing vector index configuration. يُرجى إنشاء الفهرس المطلوب باستخدام الأمر gcloud التالي: ..."رسالة خطأ في &quot;مستكشف السجلّات&quot;
  8. تحتوي رسالة الخطأ أيضًا على الأمر gcloud الذي يجب تشغيله لإعداد الفهرس المفقود.
  9. شغّل الأمر التالي من سطر الأوامر. إذا لم يكن gcloud CLI مثبّتًا على جهازك، اتّبِع التعليمات الواردة هنا لتثبيته.
    gcloud alpha firestore indexes composite create --project=INSERT-YOUR=PROJECT-ID-HERE --collection-group=notes --query-scope=COLLECTION --field-config=vector-config='{"dimension":"768","flat": "{}"}',field-path=embedding
    
    يستغرق إنشاء الفهرس بضع دقائق. يمكنك التحقّق من مستوى التقدّم في علامة التبويب الفهارس ضمن قسم Firestore في وحدة تحكّم Firebase.حالة الفهرس الجديد
  10. بعد إعداد الفهرس، يمكنك إنشاء مستند طلب بحث جديد.
  11. من المفترض أن تظهر لك الآن قائمة بمعرّفات المستندات المتطابقة في حقل النتائجنتيجة تنفيذ طلب بحث دلالي
  12. انسخ أحد أرقام التعريف هذه، وارجع إلى مجموعة notes.
  13. استخدِم ⌘+F للبحث عن رقم تعريف المستند الذي نسخته، فهو المستند الذي يتطابق بشكل أفضل مع طلب البحث.العثور على رقم تعريف المستند في قائمة المستندات

7- تنفيذ البحث الدلالي

لقد حان الوقت أخيرًا لربط تطبيقك المتوافق مع الأجهزة الجوّالة بإضافة Vector Search مع Firestore وتنفيذ ميزة البحث الدلالي التي ستسمح للمستخدمين بالبحث في ملاحظاتهم باستخدام طلبات بحث بلغة طبيعية.

ربط الدالة القابلة للاستدعاء لإجراء طلبات بحث

تتضمّن إضافة "البحث باستخدام المتجهات مع Firestore" دالة Cloud يمكنك الاتصال بها من تطبيقك المتوافق مع الأجهزة الجوّالة لطلب البحث في الفهرس الذي أنشأته سابقًا في هذا الدليل التعليمي. في هذه الخطوة، ستُنشئ اتصالاً بين تطبيقك المتوافق مع الأجهزة الجوّالة وهذه الدالة القابلة للاتّصال. تتضمّن حزمة تطوير البرامج (SDK) Swift من Firebase واجهات برمجة تطبيقات تسهّل استدعاء الدوال البرمجية البعيدة.

  1. ارجع إلى Xcode وتأكَّد من أنّك في المشروع الذي نسخته في خطوة سابقة في هذا الدليل التعليمي.
  2. افتح ملف NotesRepository.swift.
  3. ابحث عن السطر الذي يحتوي على private lazy var vectorSearchQueryCallable: Callable = functions.httpsCallable("").

لاستدعاء دالة Cloud قابلة للاستدعاء، عليك تقديم اسم الدالة التي تريد استدعاؤها.

  1. انتقِل إلى وحدة تحكُّم Firebase لمشروعك، وافتح عنصر قائمة الدوالّ في قسم إنشاء.
  2. ستظهر لك قائمة بالدوال التي تمّ تثبيتها بواسطة الإضافة.
  3. ابحث عن الجهاز الذي يحمل الاسم ext-firestore-vector-search-queryCallable وانسخ اسمه.
  4. الصق الاسم في التعليمة البرمجية. من المفترض أن يظهر الآن
    private lazy var vectorSearchQueryCallable: Callable<String, String> = functions.httpsCallable("ext-firestore-vector-search-queryCallable")
    

استدعاء دالة الاستعلام

  1. العثور على الطريقة performQuery
  2. استدعاء الدالة القابلة للاستدعاء من خلال استدعاء
    let result = try await vectorSearchQueryCallable(searchTerm)
    

بما أنّ هذه مكالمة عن بُعد، قد يتعذّر إجراؤها.

  1. أضِف بعض الإجراءات الأساسية لمعالجة الأخطاء من أجل رصد أي أخطاء وتسجيلها في وحدة تحكّم Xcode.
    private func performQuery(searchTerm: String) async -> [String] {
      do {
        let result = try await vectorSearchQueryCallable(searchTerm)
        return [result]
      }
      catch {
        print(error.localizedDescription)
        return []
      }
    }
    

ربط واجهة المستخدم

للسماح للمستخدمين بالبحث في ملاحظاتهم، ستقوم بتنفيذ شريط بحث في شاشة قائمة الملاحظات. عندما يكتب المستخدِم عبارة بحث، عليك استدعاء طريقة performQuery التي نفّذتها في الخطوة السابقة. بفضل مُعدِّلات العرض searchable وtask التي يوفّرها SwiftUI، لا يتطلّب ذلك سوى بضعة أسطر من الرموز البرمجية.

  1. أولاً، افتح NotesListScreen.swift
  2. لإضافة مربّع بحث إلى عرض القائمة، أضِف مُعدِّل العرض .searchable(text: $searchTerm, prompt: "Search") فوق السطر .navigationTitle("Notes") مباشرةً.
  3. بعد ذلك، استدعِ دالة البحث بإضافة التعليمة البرمجية التالية أدناه مباشرةً:
.task(id: searchTerm, debounce: .milliseconds(800)) {
  await notesRepository.semanticSearch(searchTerm: searchTerm)
}

يُطلِق مقتطف الرمز البرمجي هذا طريقة semanticSearch بشكل غير متزامن. من خلال توفير مهلة تبلغ 800 ملي ثانية، يمكنك توجيه مُعدِّل المهام إلى إيقاف إدخال المستخدم مؤقتًا لمدة 0.8 ثانية. وهذا يعني أنّه لن يتم طلب الدالة semanticSearch إلا بعد أن يتوقّف المستخدم مؤقتًا عن الكتابة لأكثر من 0.8 ثانية.

من المفترض أن تظهر علامتك البرمجية الآن على النحو التالي:

...
List(repository.notes) { note in
  NavigationLink(value: note) {
    NoteRowView(note: note)
  }
  .swipeActions {
    Button(role: .destructive, action: { deleteNote(note: note) }) {
      Label("Delete", systemImage: "trash")
    }
  }
}
.searchable(text: $searchTerm, prompt: "Search")
.task(id: searchTerm, debounce: .milliseconds(800)) {
  await notesRepository.semanticSearch(searchTerm: searchTerm)
}
.navigationTitle("Notes")
...

تشغيل التطبيق

  1. اضغط على ⌘ + R (أو انقر على الزر "تشغيل") لتشغيل التطبيق على "محاكي iOS".
  2. من المفترض أن تظهر لك الملاحظات نفسها التي أضفتها في التطبيق سابقًا في هذا الدرس التطبيقي حول الترميز، بالإضافة إلى أي ملاحظات أضفتها عبر وحدة تحكُّم Firebase.
  3. من المفترض أن يظهر لك حقل بحث في أعلى قائمة الملاحظات.
  4. اكتب عبارة تظهر في أحد المستندات التي أضفتها. مرة أخرى، يعمل هذا الإجراء بشكل أفضل مع طلبات البحث الدلالية، مثل "كيف يمكنني استدعاء واجهات برمجة التطبيقات غير المتزامنة في Firebase من Swift" (شرط أن تحتوي ملاحظة واحدة على الأقل من الملاحظات التي أضفتها على نص يتناول هذا الموضوع).
  5. من المرجّح أن تظهر لك نتيجة البحث، ولكن بدلاً من ذلك، تكون طريقة عرض القائمة فارغة، وتعرض وحدة تحكّم Xcode رسالة خطأ: "تمّ استدعاء الدالة باستخدام مَعلمة غير صالحة".

تطبيق &quot;ملاحظات Google&quot;، مع قائمة نتائج فارغة

هذا يعني أنّك أرسلت البيانات بتنسيق غير صحيح.

تحليل رسالة الخطأ

  1. لمعرفة المشكلة، انتقِل إلى وحدة تحكُّم Firebase.
  2. انتقِل إلى قسم الدوالّ.
  3. ابحث عن الدالة ext-firestore-vector-search-queryCallable، وافتح قائمة الخيارات الإضافية بالنقر على النقاط الثلاث الرأسية.
  4. انقر على عرض السجلات للانتقال إلى "مستكشف السجلات".
  5. من المفترض أن تظهر لك رسالة خطأ.
Unhandled error ZodError: [
  {
    "code": "invalid_type",
    "expected": "object",
    "received": "string",
    "path": [],
    "message": "Expected object, received string"
  }
]

هذا يعني أنّك أرسلت البيانات بتنسيق غير صحيح.

استخدام أنواع البيانات الصحيحة

لمعرفة التنسيق الذي تتوقّع الإضافة أن تكون فيه المَعلمات، اطّلِع على مستندات الإضافة.

  1. انتقِل إلى قسم الإضافات في "وحدة تحكُّم Firebase".
  2. انقر على إدارة ->إدارة إضافة &quot;البحث المتجه&quot; باستخدام Firestore.
  3. في قسم طريقة عمل هذه الإضافة، ستجد مواصفات لمَعلمات الإدخال والإخراج.توثيق لمَعلمة الإدخال وقيمة النتيجة
  4. ارجع إلى Xcode وانتقِل إلى NotesRepository.swift.
  5. أضِف الرمز البرمجي التالي في بداية الملف:
    private struct QueryRequest: Codable {
      var query: String
      var limit: Int?
      var prefilters: [QueryFilter]?
    }
    
    private struct QueryFilter: Codable {
      var field: String
      var `operator`: String
      var value: String
    
    }
    
    private struct QueryResponse: Codable {
      var ids: [String]
    }
    
    QueryRequest تطابق بنية مَعلمة الإدخال التي تتوقّعها الإضافة، وفقًا لمستندات الإضافة. وتحتوي أيضًا على سمة prefilter مدمَجة ستحتاج إليها لاحقًا.وتتطابق QueryResponse مع بنية استجابة الإضافة.
  6. العثور على مواصفات الدالة القابلة للاتّباع وتعديل نوعَي الإدخال والإخراج
    private lazy var vectorSearchQueryCallable: Callable<QueryRequest, QueryResponse> = functions.httpsCallable("ext-firestore-vector-search-queryCallable")
    
  7. تعديل استدعاء الدالة القابلة للاستدعاء في performQuery
    private func performQuery(searchTerm: String) async -> [String] {
      do {
        let queryRequest = QueryRequest(query: searchTerm,
                                        limit: 2)
        let result = try await vectorSearchQueryCallable(queryRequest)
        print(result.ids)
        return result.ids
      }
      catch {
        print(error.localizedDescription)
        return []
      }
    }
    

تشغيل التطبيق مرة أخرى

  1. تشغيل التطبيق مرة أخرى
  2. اكتب طلب بحث يحتوي على عبارات مضمّنة في إحدى ملاحظاتك.
  3. من المفترض أن تظهر لك الآن قائمة مفلتَرة بالملاحظات.

لقطة شاشة للتطبيق مع النتيجة المتوقّعة

فلترة بيانات المستخدمين مسبقًا

قبل بدء الرقص للاحتفال - هناك مشكلة في الإصدار الحالي من التطبيق: تحتوي مجموعة النتائج على بيانات من جميع المستخدمين.

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

إذا أجريت عملية بحث، ستلاحظ أنّ طلب vectorSearchQueryCallable يعرض أرقام تعريف المستندات التي قد تنتمي إلى المستخدم الآخر. لمنع حدوث ذلك، علينا استخدام فلتر أولي.

في performQuery، عدِّل الرمز على النحو التالي:

  let prefilters: [QueryFilter] = if let uid = user?.uid {
    [QueryFilter(field: "userId", operator: "==", value: uid)]
  }
  else {
    []
  }

  let queryRequest = QueryRequest(query: searchTerm,
                                  limit: 2,
                                  prefilters: prefilters)

سيؤدي ذلك إلى فلترة البيانات مسبقًا استنادًا إلى رقم تعريف المستخدم الذي سجّل الدخول. ويتطلّب ذلك تحديث فهرس Firestore.

شغِّل الأمر التالي من سطر الأوامر لتحديد فهرس جديد في Firestore يتضمن كلاً من userId وعمليات تضمين المتجه في الحقل embedding.

gcloud alpha firestore indexes composite create --project=INSERT-YOUR-PROJECT-ID-HERE --collection-group=notes --query-scope=COLLECTION --field-config=order=ASCENDING,field-path=userId --field-config=vector-config='{"dimension":"768","flat": "{}"}',field-path=embedding

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

مجموعة النتائج التي تمّت فلترتها مسبقًا

8- تهانينا

تهانينا على إكمال هذا الدليل التعليمي للترميز بنجاح.

في هذا الدليل التعليمي للترميز، تعرّفت على كيفية:

  • إعداد قاعدة بيانات Cloud Firestore مع تفعيل البحث الدلالي
  • إنشاء تطبيق SwiftUI بسيط للتفاعل مع قاعدة البيانات.
  • يمكنك تنفيذ شريط بحث باستخدام مُعدِّل العرض القابل للبحث في SwiftUI ومُعدِّل المَهمّة.
  • استدعاء إحدى وظائف Cloud لإجراء بحث دلالي في قاعدة البيانات باستخدام واجهة Callable في حزمة تطوير البرامج (SDK) لمنصّة Firestore

من خلال المعرفة التي اكتسبتها في هذا الدرس التطبيقي حول الترميز، يمكنك الآن إنشاء تطبيقات فعّالة تستفيد من إمكانات البحث الدلالي في Cloud Firestore لمنح المستخدمين تجربة بحث أكثر سهولة وفعالية.

لمزيد من المعلومات حول حقل المتجه الجديد في Firestore وكيفية حساب تضمينات المتجهات، يُرجى الاطّلاع على المستندات.