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

1. نظرة عامة

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

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

ما ستتعلمه

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

المتطلبات

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

2. إنشاء مشروع Firebase وإعداده

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

إنشاء مشروع Firebase

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

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

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

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

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

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

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

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

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

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

تفعيل المصادقة بدون الكشف عن الهوية في Firebase Authentication

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

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

إعداد Cloud Firestore

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

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

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

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

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

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

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

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

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

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

4. تثبيت إضافة "البحث المتّجهي مع Firestore"

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

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

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

ضبط الإضافة

  1. راجِع واجهات برمجة التطبيقات المفعَّلة والموارد التي تم إنشاؤها.مراجعة واجهات برمجة التطبيقات المفعَّلة
  2. فعِّل الخدمات المطلوبة.تفعيل الخدمات المطلوبة
  3. بعد تفعيل جميع الخدمات، انقر على التالي.انقر على "التالي" بعد تفعيل جميع الخدمات.
  4. راجِع الأذونات الممنوحة لهذه الإضافة.
  5. ضبط الإضافة:
    • اختَر Vertex AI كـ نموذج لغوي كبير.
    • مسار المجموعة: notes
    • الحدّ التلقائي لطلبات البحث: 3
    • اسم حقل الإدخال: text
    • اسم حقل الإخراج: embedding
    • اسم حقل الحالة:* *الحالة*
    • تضمين المستندات الحالية: نعم
    • تعديل المستندات الحالية: نعم
    • موقع 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 Console الخاص بمشروعك باتّباع هذا الرابط، ثم اختَر مشروعك من القائمةاختيار المشروع الصحيح
  7. في "مستكشف سجلات Cloud"، من المفترض أن تظهر لك الآن رسالة خطأ تفيد بأنّ "FAILED_PRECONDITION: Missing vector index configuration". يُرجى إنشاء الفهرس المطلوب باستخدام أمر gcloud التالي: ..."رسالة الخطأ في &quot;مستكشف السجلّ&quot;
  8. تحتوي رسالة الخطأ أيضًا على الأمر gcloud الذي يجب تنفيذه لإعداد الفهرس الناقص.
  9. نفِّذ الأمر التالي من سطر الأوامر. إذا لم يكن لديك واجهة سطر الأوامر gcloud مثبَّتة على جهازك، اتّبِع التعليمات الواردة هنا لتثبيتها.
    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. تنفيذ البحث الدلالي

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

ربط الدالة القابلة للاستدعاء لتنفيذ طلبات البحث

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

  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;الملاحظات&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.
  • استدعاء إحدى "وظائف السحابة" لإجراء بحث دلالي في قاعدة البيانات باستخدام واجهة Callable في حزمة تطوير البرامج (SDK) الخاصة بخدمة Firestore

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

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