1. نظرة عامة
في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كيفية إضافة ميزات بحث فعّالة إلى تطبيقك باستخدام بحث التشابه بين المتجهات في Firestore. ستنفِّذ ميزة البحث الدلالي لتطبيق تدوين ملاحظات مكتوب بلغتَي Swift وSwiftUI.
ما ستتعرّف عليه
- كيفية تثبيت إضافة "البحث بالاستناد إلى المتجهات" مع Firestore لاحتساب عمليات إدراج المتجهات
- كيفية استدعاء وظائف Firebase Cloud من تطبيق Swift
- كيفية فلترة البيانات مسبقًا استنادًا إلى المستخدم الذي سجّل الدخول
ما ستحتاجه
- Xcode 15.3
- نموذج التعليمات البرمجية في ورشة التعلم بالبرمجة وسيتم تنزيل هذا الملف في خطوة لاحقة من ورشة رموز البرامج.
2- إنشاء مشروع على Firebase وإعداده
لاستخدام إضافة "بحث المتجهات" من Firebase، تحتاج إلى مشروع على Firebase. في هذا الجزء من ورشة رموز البرامج، ستنشئ مشروعًا جديدًا على Firebase وتفعّل الخدمات المطلوبة، مثل Cloud Firestore وFirebase Authentication.
إنشاء مشروع على Firebase
- سجِّل الدخول إلى Firebase.
- في "وحدة تحكّم Firebase"، انقر على إضافة مشروع، ثمّ أدخِل اسمًا لمشروعك هو Firestore Vector Search Lab
.
- انقر على خيارات إنشاء المشروع. اقبل بنود Firebase إذا طُلب منك ذلك.
- في شاشة "إحصاءات Google"، أزِل العلامة من المربّع تفعيل "إحصاءات Google" لهذا المشروع، لأنّك لن تستخدم "إحصاءات Google" لهذا التطبيق.
- أخيرًا، انقر على إنشاء مشروع.
لمزيد من المعلومات عن مشاريع Firebase، اطّلِع على مقالة التعرّف على مشاريع Firebase.
ترقية خطة أسعار Firebase
لاستخدام "إضافات Firebase" وخدمات السحابة الإلكترونية الأساسية، يجب أن يكون مشروعك على Firebase مُدرَجًا في خطة الأسعار "الدفع حسب الاستخدام" (Blaze)، ما يعني أنّه مرتبط بحساب على Cloud Billing.
- يتطلب حساب "الفوترة في Google Cloud" طريقة دفع، مثل بطاقة الائتمان.
- إذا كنت حديث العهد باستخدام Firebase وGoogle Cloud، تحقّق ممّا إذا كنت مؤهلاً للحصول على رصيد بقيمة 300 دولار أمريكي وحساب "الفوترة في السحابة الإلكترونية" في الفترة التجريبية المجانية.
- إذا كنت تُجري هذا الإصدار التجريبي من رمز المصدر كجزء من حدث، اسأل المنظِّم ما إذا كانت هناك أي أرصدة متاحة في Cloud.
لترقية مشروعك إلى خطة Blaze، اتّبِع الخطوات التالية:
- في "وحدة تحكُّم Firebase"، اختَر ترقية خطتك.
- اختَر خطة Blaze. اتّبِع التعليمات الظاهرة على الشاشة لربط حساب "فوترة على Cloud" بمشروعك.
إذا كنت بحاجة إلى إنشاء حساب "فوترة على Cloud" كجزء من هذه الترقية، قد تحتاج إلى الرجوع إلى مسار الترقية في وحدة تحكّم Firebase لإكمال الترقية.
تفعيل منتجات Firebase وإعدادها في وحدة التحكّم
يستخدم التطبيق الذي تنشئه العديد من منتجات Firebase المتاحة لتطبيقات Apple:
- Firebase Authentication للسماح للمستخدمين بتسجيل الدخول إلى تطبيقك بسهولة
- Cloud Firestore لحفظ البيانات المنظَّمة في السحابة الإلكترونية والحصول على إشعار فوري عند تغيُّر البيانات
- قواعد أمان Firebase لتأمين قاعدة بياناتك
وتتطلّب بعض هذه المنتجات إعدادًا خاصًا أو تفعيلها باستخدام وحدة تحكُّم Firebase.
تفعيل المصادقة المجهولة في Firebase Authentication
يستخدم هذا التطبيق المصادقة المجهولة للسماح للمستخدمين ببدء استخدام التطبيق بدون الحاجة إلى إنشاء حساب أولاً. ويؤدي ذلك إلى عملية إعداد سهلة. لمزيد من المعلومات عن المصادقة المجهولة الهوية (وكيفية الترقية إلى حساب يحمل اسمًا)، يُرجى الاطّلاع على أفضل الممارسات للمصادقة المجهولة الهوية.
- في اللوحة اليمنى من وحدة تحكّم Firebase، انقر على الإنشاء > المصادقة. بعد ذلك، انقر على البدء.
- لقد انتقلت الآن إلى لوحة بيانات المصادقة، حيث يمكنك الاطّلاع على المستخدمين الذين سجّلوا الدخول وضبط مقدّمي خدمات تسجيل الدخول وإدارة الإعدادات.
- انقر على علامة التبويب طريقة تسجيل الدخول (أو انقر على هذا الرابط للانتقال مباشرةً إلى علامة التبويب).
- انقر على غير محدّد من خيارات مقدّم الخدمة، ثمّ فعِّل الخيار تفعيل، ثمّ انقر على حفظ.
إعداد Cloud Firestore
يستخدم تطبيق Swift هذا Cloud Firestore لحفظ الملاحظات.
في ما يلي كيفية إعداد Cloud Firestore في مشروعك على Firebase:
- في اللوحة اليمنى من وحدة تحكّم Firebase، وسِّع الإنشاء، ثم اختَر قاعدة بيانات Firestore.
- انقر على إنشاء قاعدة بيانات.
- اترك رقم تعريف قاعدة البيانات مضبوطًا على
(default)
. - اختَر موقعًا لقاعدة بياناتك، ثم انقر على التالي.
بالنسبة إلى التطبيق الحقيقي، عليك اختيار موقع قريب من المستخدمين. - انقر على البدء في وضع الاختبار. اقرأ بيان إخلاء المسؤولية بشأن قواعد الأمان.
في وقت لاحق من هذا الدليل التعليمي، ستضيف قواعد أمان لتأمين بياناتك. لا توزِّع تطبيقًا علنًا أو تعرضه بدون إضافة قواعد أمان لقاعدة بياناتك. - انقر على إنشاء.
إعداد "مساحة التخزين في السحابة الإلكترونية" لبرنامج Firebase
يستخدم تطبيق الويب ميزة "التخزين في السحابة الإلكترونية" من Firebase لتخزين الصور وتحميلها ومشاركتها.
في ما يلي كيفية إعداد ميزة "التخزين في السحابة الإلكترونية" لبرنامج Firebase في مشروعك على Firebase:
- في اللوحة اليمنى من وحدة تحكّم Firebase، وسِّع الإصدار، ثم اختَر مساحة التخزين.
- انقر على البدء.
- اختَر موقعًا جغرافيًا لحزمة التخزين التلقائية.
يمكن للحِزم فيUS-WEST1
وUS-CENTRAL1
وUS-EAST1
الاستفادة من المستوى"مجاني دائمًا" في Google Cloud Storage. تخضع الحِزم في جميع المواقع الجغرافية الأخرى لأسعار Google Cloud Storage واستخدامها. - انقر على البدء في وضع الاختبار. اقرأ بيان إخلاء المسؤولية بشأن قواعد الأمان.
في وقت لاحق من هذا الدليل التعليمي، ستضيف قواعد أمان لتأمين بياناتك. لا توزِّع تطبيقًا علنًا أو تعرضه بدون إضافة قواعد أمان لحزمة التخزين. - انقر على إنشاء.
3- ربط تطبيق الأجهزة الجوّالة
في هذا القسم من ورشة رموز البرامج، ستنزِّل رمز المصدر لتطبيق بسيط لتسجيل الملاحظات، وتربطه بمشروع Firebase الذي أنشأته للتو.
تنزيل نموذج التطبيق
- انتقِل إلى https://github.com/FirebaseExtended/codelab-firestore-vectorsearch-ios، وانسخ المستودع إلى جهازك المحلي.
- افتح مشروع Notes.xcodeproj في Xcode.
ربط التطبيق بمشروعك على Firebase
لكي يتمكّن تطبيقك من الوصول إلى خدمات Firebase، عليك إعداد التطبيق في وحدة تحكّم Firebase. يمكنك ربط تطبيقات عملاء متعددة بمشروع Firebase نفسه. على سبيل المثال، إذا أنشأت تطبيق Android أو تطبيق ويب، عليك ربطهما بمشروع Firebase نفسه.
لمزيد من المعلومات عن مشاريع Firebase، اطّلِع على مقالة فهم مشاريع Firebase.
- في "وحدة تحكُّم Firebase"، انتقِل إلى صفحة النظرة العامة على مشروعك على Firebase.
- انقر على رمز iOS+ لإضافة تطبيق iOS.
- في شاشة إضافة Firebase إلى تطبيق Apple، أدخِل رقم تعريف الحِزمة من مشروع Xcode (com.google.firebase.codelab.Notes).
- يمكنك إدخال اسم مختصر للتطبيق إذا أردت (ملاحظات حول أجهزة iOS).
- انقر على "تسجيل التطبيق" للانتقال إلى الخطوة التالية.
- نزِّل ملف GoogleServices-Info.plist.
- اسحب GoogleServices-Info.plist إلى مجلد Notes في مشروع Xcode. من الطرق الجيدة لإجراء ذلك إسقاطه أسفل ملف Assets.xcassets.
- اختَر نسخ العناصر إذا لزم الأمر، وتأكَّد من اختيار استهداف الملاحظات في الإضافة إلى الاستهدافات، ثم انقر على إنهاء.
- في وحدة تحكّم Firebase، يمكنك الآن النقر على باقي خطوات عملية الإعداد: تم تثبيت حزمة تطوير البرامج (SDK) لمنصّة Apple من Firebase في العيّنة التي نزّلتها في بداية هذا القسم، وتم إعداد عملية الإعداد الأولي. يمكنك إنهاء العملية من خلال النقر على متابعة إلى وحدة التحكّم.
تشغيل التطبيق
حان الآن وقت تجربة التطبيق.
- في Xcode، شغِّل التطبيق على "محاكي iOS". في القائمة المنسدلة Run Destinations (الوجهات التي سيتم تشغيل التطبيق عليها)، اختَر أولاً أحد محاكيات iOS.
- بعد ذلك، انقر على الزر تشغيل أو اضغط على ⌘ + R.
- بعد تشغيل التطبيق بنجاح على المحاكي، أضِف بضع ملاحظات.
- في وحدة تحكُّم Firebase، انتقِل إلى متصفّح بيانات Firestore، حتى تتمكّن من الاطّلاع على المستندات الجديدة التي يتم إنشاؤها عند إضافة ملاحظات جديدة في التطبيق.
4. تثبيت إضافة "البحث باستخدام المتجهات" مع Firestore
في هذا الجزء من "مختبر الرموز البرمجية"، ستثبّت إضافة "البحث المرئي" باستخدام Firestore، وسيتم ضبطها وفقًا لمتطلبات تطبيق تدوين الملاحظات الذي تعمل عليه.
بدء تثبيت الإضافة
- في قسم Firestore، انقر على علامة التبويب الإضافات.
- انقر على استكشاف مركز الإضافات.
- اكتب "vector".
- انقر على "بحث متجه باستخدام إضافة Firestore".
سينقلك هذا الإجراء إلى صفحة تفاصيل الإضافة، حيث يمكنك الاطّلاع على مزيد من المعلومات حول الإضافة وطريقة عملها وخدمات Firebase التي تتطلّبها وكيفية ضبطها.
- انقر على التثبيت في وحدة تحكُّم Firebase.
- ستظهر لك قائمة بجميع مشاريعك.
- اختَر المشروع الذي أنشأته في الخطوة الأولى من هذا الدليل التعليمي.
ضبط الإضافة
- راجِع واجهات برمجة التطبيقات المفعَّلة والموارد التي تم إنشاؤها.
- فعِّل الخدمات المطلوبة.
- بعد تفعيل جميع الخدمات، انقر على التالي.
- راجِع الأذونات الممنوحة لهذه الإضافة.
- ضبط الإضافة:
- اختَر Vertex AI كـ النموذج اللغوي الكبير.
- مسار المجموعة: notes
- الحدّ الأقصى التلقائي لطلبات البحث: 3
- اسم حقل الإدخال: text
- اسم حقل الإخراج: embedding
- اسم حقل الحالة:* *status*
- تضمين المستندات الحالية: نعم
- تعديل المستندات الحالية: نعم
- موقع Cloud Function: us-central1
- انقر على تثبيت الإضافة لإكمال عملية التثبيت.
قد يستغرق ذلك بضع دقائق. أثناء انتظار اكتمال عملية التثبيت، يمكنك الانتقال إلى القسم التالي من البرنامج التعليمي وقراءة بعض المعلومات الأساسية عن عمليات إدراج المتجهات.
5- الخلفية
أثناء انتظار اكتمال عملية التثبيت، إليك بعض المعلومات الأساسية حول آلية عمل إضافة "البحث المرئي" مع Firestore.
ما هي المتجهات والعناصر المضمّنة وقواعد بيانات المتجهات؟
- المتجهات هي عناصر رياضية تمثّل مقدار كمية معيّنة واتجاهها. ويمكن استخدامها لتمثيل البيانات بطريقة تسهّل المقارنة والبحث.
- العناصر المضمّنة هي متجهات تمثّل معنى كلمة أو عبارة. ويتم إنشاؤها من خلال تدريب شبكة عصبية على مجموعة كبيرة من النصوص ومعرفة العلاقات بين الكلمات.
- قواعد بيانات الرسومات المتجهّة هي قواعد بيانات محسّنة لتخزين بيانات الرسومات المتجهّة والبحث عنها. وتسمح هذه التقنيات بإجراء بحث فعّال عن أقرب العناصر المتشابهة، وهي عملية العثور على المتجهات الأكثر تشابهًا مع متجه طلب بحث معيّن.
كيف تعمل ميزة "البحث بالاستناد إلى الرسومات"؟
تعمل ميزة "البحث باستخدام المتجهات" من خلال مقارنة متجه طلب البحث بجميع المتجهات في قاعدة البيانات. يتم عرض المتجهات الأكثر تشابهًا مع متجه الطلب كنتائج البحث.
يمكن قياس التشابه بين متجهَين باستخدام مجموعة متنوعة من مقاييس المسافة. إنّ مقياس المسافة الأكثر شيوعًا هو تشابه جيب التمام الذي يقيس الزاوية بين متجهَين.
6- تجربة إضافة "البحث باستخدام المتجهات" مع Firestore
قبل استخدام إضافة "البحث المرئي" مع Firestore في تطبيق iOS الذي نزّلته سابقًا في هذا الدليل التعليمي حول رموز البرامج، يمكنك تجربة الإضافة في وحدة تحكّم Firebase.
قراءة المستندات
تتضمّن إضافات Firebase مستندات حول آلية عملها.
- بعد انتهاء تثبيت الإضافة، انقر على الزر البدء.
- اطّلِع على علامة التبويب "طريقة عمل هذه الإضافة" التي توضّح ما يلي:
- كيفية احتساب عمليات التضمين للمستندات من خلال إضافتها إلى مجموعة
notes
- كيفية إجراء طلب بحث في الفهرس من خلال استدعاء الدالة القابلة للاستدعاء
ext-firestore-vector-search-queryCallable
- أو كيفية البحث في الفهرس عن طريق إضافة مستند طلب بحث إلى مجموعة
_firestore-vector-search/index/queries
. - ويوضّح أيضًا كيفية إعداد دالة تضمين مخصّصة، وهو أمر مفيد إذا لم تستوفِ أي من النماذج اللغوية الكبيرة المتوافقة مع الإضافة متطلباتك، وأردت استخدام نموذج لغوي كبير مختلف لاحتساب عمليات الدمج.
- كيفية احتساب عمليات التضمين للمستندات من خلال إضافتها إلى مجموعة
- انقر على رابط لوحة بيانات Cloud Firestore للانتقال إلى نسختك من Firestore.
- انتقِل إلى مستند
_firestore-vector-search/index
. من المفترض أن يُظهر ذلك أنّ الإضافة قد أكملت احتساب عمليات التضمين لجميع مستندات الملاحظات التي أنشأتها في خطوة سابقة في هذا الدليل التعليمي حول الرموز البرمجية. - للتأكّد من ذلك، افتح أحد مستندات الملاحظات، ومن المفترض أن يظهر لك حقل إضافي باسم
embedding
من النوعvector<768>
، بالإضافة إلى حقلstatus
.
إنشاء نموذج مستند
يمكنك إنشاء مستند جديد في وحدة تحكّم Firebase للاطّلاع على الإضافة أثناء عملها.
- لا تزال في متصفّح بيانات Firestore، انتقِل إلى مجموعة
notes
وانقر على + إضافة مستند في العمود الأوسط. - انقر على المعرّف التلقائي لإنشاء معرّف مستند فريد جديد.
- أضِف حقلًا باسم
text
من النوع سلسلة، والصِق بعض النصوص في حقل القيمة. من المهم ألا يكون هذا النص عبارة عن نص Lorem ipsum أو أي نص عشوائي آخر. اختَر مقالة إخبارية، على سبيل المثال. - انقر على حفظ.
- لاحظ كيف تضيف الإضافة حقل حالة للإشارة إلى أنّها تعالج البيانات.
- بعد فترة قصيرة، من المفترض أن يظهر لك حقل جديد
embedding
بقيمةvector<768>
.
إجراء طلب بحث
تتضمّن إضافة "بحث المتجهات" مع Firestore ميزة صغيرة رائعة تتيح لك البحث في فهرس المستندات بدون الحاجة إلى ربط تطبيق.
- في قسم Firestore ضمن وحدة تحكّم Firebase، انتقِل إلى مستند
_firestore-vector-search/index
. - انقر على + بدء مجموعة
.
- أنشئ مجموعة فرعية جديدة باسم
queries
. - أنشئ مستندًا جديدًا واضبط الحقل
query
على نص يظهر في أحد مستنداتك. يعمل هذا الإجراء بشكل أفضل مع طلبات البحث الدلالية، مثل "كيف يمكنني ربط مستندات Firestore باستخدام Swift" (شرط أن تحتوي ملاحظة واحدة على الأقل من الملاحظات التي أضفتها على نص يتناول هذا الموضوع). - قد تظهر لك رسالة خطأ في حالة التطبيق
- ويعود السبب في ذلك إلى عدم توفّر فهرس. لإعداد إعدادات الفهرس غير المتوفّرة، انتقِل إلى وحدة تحكّم Google Cloud لمشروعك باتّباع هذا الرابط، ثم اختَر مشروعك من القائمة.
- في "مستكشف سجلّات Cloud"، من المفترض أن تظهر لك الآن رسالة خطأ تفيد بأنّ "FAILED_PRECONDITION: Missing vector index configuration. يُرجى إنشاء الفهرس المطلوب باستخدام الأمر gcloud التالي: ..."
- تحتوي رسالة الخطأ أيضًا على أمر
gcloud
يجب تنفيذه لضبط الفهرس المفقود. - نفِّذ الأمر التالي من سطر الأوامر. إذا لم يكن
gcloud
CLI مثبّتًا على جهازك، اتّبِع التعليمات الواردة هنا لتثبيته. يستغرق إنشاء الفهرس بضع دقائق. يمكنك التحقّق من مستوى التقدّم في علامة التبويب الفهارس ضمن قسم Firestore في وحدة تحكّم Firebase.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
- بعد إعداد الفهرس، يمكنك إنشاء مستند طلب بحث جديد.
- من المفترض أن تظهر لك الآن قائمة بأرقام تعريف المستندات المطابقة في حقل النتائج.
- انسخ أحد أرقام التعريف هذه، ثم ارجع إلى مجموعة
notes
. - استخدِم ⌘+F للبحث عن رقم تعريف المستند الذي نسخته، فهو المستند الذي يتطابق بشكل أفضل مع طلب البحث.
7. تنفيذ البحث الدلالي
لقد حان الوقت أخيرًا لربط تطبيقك المتوافق مع الأجهزة الجوّالة بإضافة Vector Search مع Firestore وتنفيذ ميزة البحث الدلالي التي ستسمح للمستخدمين بالبحث في ملاحظاتهم باستخدام طلبات بحث بلغة طبيعية.
ربط الدالة القابلة للاستدعاء لإجراء طلبات بحث
تتضمّن إضافة "البحث المتجه باستخدام Firestore" دالة Cloud Function يمكنك الاتصال بها من تطبيقك المتوافق مع الأجهزة الجوّالة لطلب البحث في الفهرس الذي أنشأته سابقًا في هذا الدليل التعليمي. في هذه الخطوة، ستُنشئ اتصالاً بين تطبيقك المتوافق مع الأجهزة الجوّالة وهذه الدالة القابلة للاتّصال. تتضمّن حزمة تطوير البرامج (SDK) Swift من Firebase واجهات برمجة تطبيقات تسهّل استدعاء الدوال البرمجية البعيدة.
- ارجع إلى Xcode وتأكَّد من أنّك في المشروع الذي نسخته في خطوة سابقة في هذا الدليل التعليمي.
- افتح ملف
NotesRepository.swift
. - ابحث عن السطر الذي يحتوي على
private lazy var vectorSearchQueryCallable: Callable
.= functions.httpsCallable("")
لاستدعاء دالة قابلة للاتّصال في Cloud، عليك تقديم اسم الدالة التي تريد استدعاؤها.
- انتقِل إلى "وحدة تحكُّم Firebase" لمشروعك، وافتح عنصر قائمة Functions في قسم الإنشاء.
- ستظهر لك قائمة بالدوالّ التي تم تثبيتها من خلال الإضافة.
- ابحث عن الجهاز الذي يحمل الاسم
ext-firestore-vector-search-queryCallable
وانسخ اسمه. - الصِق الاسم في الرمز. من المفترض أن يظهر الآن
private lazy var vectorSearchQueryCallable: Callable<String, String> = functions.httpsCallable("ext-firestore-vector-search-queryCallable")
استدعاء دالة طلب البحث
- العثور على الطريقة
performQuery
- استدعاء الدالة القابلة للاستدعاء من خلال استدعاء
let result = try await vectorSearchQueryCallable(searchTerm)
بما أنّ هذه مكالمة عن بُعد، قد يتعذّر إجراؤها.
- أضِف بعض الإجراءات الأساسية لمعالجة الأخطاء من أجل رصد أي أخطاء وتسجيلها في وحدة تحكّم 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، لا يتطلّب ذلك سوى سطرَين من الرموز البرمجية.
- أولاً، افتح
NotesListScreen.swift
. - لإضافة مربّع بحث إلى عرض القائمة، أضِف مُعدِّل العرض
.searchable(text: $searchTerm, prompt: "Search")
فوق السطر.navigationTitle("Notes")
مباشرةً. - بعد ذلك، يمكنك استدعاء دالة البحث عن طريق إضافة الرمز البرمجي التالي أدناه:
.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")
...
تشغيل التطبيق
- اضغط على ⌘ + R (أو انقر على الزر "تشغيل") لتشغيل التطبيق على "محاكي iOS".
- من المفترض أن تظهر لك الملاحظات نفسها التي أضفتها في التطبيق في وقت سابق من هذا الدليل التعليمي حول رموز البرامج، بالإضافة إلى أي ملاحظات أضفتها من خلال "وحدة تحكّم Firebase".
- من المفترض أن يظهر لك حقل بحث في أعلى قائمة الملاحظات.
- اكتب عبارة تظهر في أحد المستندات التي أضفتها. مرة أخرى، يعمل هذا الإجراء بشكل أفضل مع طلبات البحث الدلالية، مثل "كيف يمكنني استدعاء واجهات برمجة التطبيقات غير المتزامنة في Firebase من Swift" (شرط أن تحتوي ملاحظة واحدة على الأقل من الملاحظات التي أضفتها على نص يتناول هذا الموضوع).
- من المرجّح أن تظهر لك نتيجة البحث، ولكن بدلاً من ذلك، تكون طريقة عرض القائمة فارغة، وتعرض وحدة تحكّم Xcode رسالة خطأ: "تمّ استدعاء الدالة باستخدام مَعلمة غير صالحة".
هذا يعني أنّك أرسلت البيانات بتنسيق غير صحيح.
تحليل رسالة الخطأ
- لمعرفة المشكلة، انتقِل إلى "وحدة تحكُّم Firebase".
- انتقِل إلى قسم الدوالّ.
- ابحث عن الدالة
ext-firestore-vector-search-queryCallable
، وافتح قائمة الخيارات الإضافية بالنقر على النقاط الثلاث الرأسية. - انقر على عرض السجلات للانتقال إلى "مستكشف السجلات".
- من المفترض أن تظهر لك رسالة خطأ.
Unhandled error ZodError: [
{
"code": "invalid_type",
"expected": "object",
"received": "string",
"path": [],
"message": "Expected object, received string"
}
]
هذا يعني أنّك أرسلت البيانات بتنسيق غير صحيح.
استخدام أنواع البيانات الصحيحة
لمعرفة التنسيق الذي تتوقّع الإضافة أن تكون فيه المَعلمات، اطّلِع على مستندات الإضافة.
- انتقِل إلى قسم الإضافات في "وحدة تحكُّم Firebase".
- انقر على إدارة ->
.
- في قسم طريقة عمل هذه الإضافة، ستجد مواصفات لمَعلمات الإدخال والإخراج.
- ارجع إلى Xcode وانتقِل إلى
NotesRepository.swift
. - أضِف الرمز البرمجي التالي في بداية الملف:
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
مع بنية استجابة الإضافة. - العثور على مواصفات الدالة القابلة للدعوة وتعديل نوعَي الإدخال والإخراج
private lazy var vectorSearchQueryCallable: Callable<QueryRequest, QueryResponse> = functions.httpsCallable("ext-firestore-vector-search-queryCallable")
- تعديل طلب تنفيذ الدالة القابلة للاستدعاء في
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 [] } }
تشغيل التطبيق مرة أخرى
- تشغيل التطبيق مرة أخرى
- اكتب طلب بحث يحتوي على عبارات مضمّنة في إحدى ملاحظاتك.
- من المفترض أن تظهر لك الآن قائمة مفلتَرة بالملاحظات.
فلترة بيانات المستخدمين مسبقًا
قبل الاحتفال، هناك مشكلة في الإصدار الحالي من التطبيق: تتضمّن مجموعة النتائج بيانات جميع المستخدمين.
يمكنك التحقّق من ذلك من خلال تشغيل التطبيق على جهاز محاكاة مختلف وإضافة المزيد من المستندات. ولن تظهر المستندات الجديدة إلا في هذا المحاكي، وإذا شغّلت التطبيق مرة أخرى على المحاكي الآخر، لن تظهر لك سوى المستندات التي أنشأتها في المرة الأولى.
إذا أجريت عملية بحث، ستلاحظ أنّ طلب 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 وكيفية احتساب عمليات إدراج المتجهات، اطّلِع على الوثائق.