1. ภาพรวม
ใน Codelab นี้ คุณจะได้ทราบวิธีเพิ่มฟีเจอร์การค้นหาที่มีประสิทธิภาพลงในแอปโดยใช้การค้นหาความคล้ายคลึงของเวกเตอร์ Firestore คุณจะใช้ฟีเจอร์การค้นหาเชิงความหมายสำหรับแอปจดโน้ตที่เขียนด้วย Swift และ SwiftUI
สิ่งที่คุณจะได้เรียนรู้
- วิธีการติดตั้งการค้นหาเวกเตอร์ที่มีส่วนขยาย Firestore เพื่อประมวลผลการฝังเวกเตอร์
- วิธีเรียกใช้ Firebase Cloud Functions จากแอปพลิเคชัน Swift
- วิธีกรองข้อมูลล่วงหน้าตามผู้ใช้ที่ลงชื่อเข้าใช้
สิ่งที่คุณต้องมี
- Xcode 15.3
- โค้ดตัวอย่างของ Codelab ซึ่งจะดาวน์โหลดได้ในขั้นตอนถัดไปของ Codelab
2. สร้างและสร้างโปรเจ็กต์ Firebase
หากต้องการใช้ส่วนขยาย Firebase Vector Search คุณต้องมีโปรเจ็กต์ Firebase ในส่วนนี้ของ Codelab คุณจะสร้างโปรเจ็กต์ Firebase ใหม่และเปิดใช้บริการที่จำเป็น เช่น Cloud Firestore และการตรวจสอบสิทธิ์ Firebase
สร้างโปรเจ็กต์ Firebase
- ลงชื่อเข้าใช้ Firebase
- ในคอนโซล Firebase ให้คลิกเพิ่มโปรเจ็กต์ จากนั้นตั้งชื่อโปรเจ็กต์ว่า Firestore Vector Search Lab
- คลิกตัวเลือกการสร้างโปรเจ็กต์ ยอมรับข้อกำหนดของ Firebase หากได้รับข้อความแจ้ง
- ในหน้าจอ Google Analytics ให้ยกเลิกการเลือกช่องเปิดใช้ Google Analytics สำหรับโปรเจ็กต์นี้ เนื่องจากคุณไม่ได้ใช้ Analytics สำหรับแอปนี้
- สุดท้าย ให้คลิกสร้างโปรเจ็กต์
ดูข้อมูลเพิ่มเติมเกี่ยวกับโปรเจ็กต์ Firebase ได้ที่ทำความเข้าใจโปรเจ็กต์ Firebase
เปิดใช้และตั้งค่าผลิตภัณฑ์ Firebase ในคอนโซล
แอปที่คุณกำลังสร้างใช้ผลิตภัณฑ์ Firebase หลายรายการที่มีให้บริการสำหรับแอป Apple ดังนี้
- การตรวจสอบสิทธิ์ของ Firebase เพื่อให้ผู้ใช้ลงชื่อเข้าใช้แอปได้อย่างง่ายดาย
- Cloud Firestore เพื่อบันทึกข้อมูลที่มีโครงสร้างในระบบคลาวด์และรับการแจ้งเตือนทันทีเมื่อข้อมูลมีการเปลี่ยนแปลง
- กฎการรักษาความปลอดภัยของ Firebase เพื่อรักษาความปลอดภัยให้ฐานข้อมูลของคุณ
ผลิตภัณฑ์เหล่านี้บางรายการต้องมีการกำหนดค่าพิเศษหรือต้องเปิดใช้โดยใช้คอนโซล Firebase
เปิดใช้การตรวจสอบสิทธิ์แบบไม่ระบุชื่อสำหรับการตรวจสอบสิทธิ์ Firebase
แอปพลิเคชันนี้ใช้การตรวจสอบสิทธิ์แบบไม่ระบุตัวตนเพื่อให้ผู้ใช้เริ่มใช้แอปได้โดยไม่ต้องสร้างบัญชีก่อน ซึ่งจะส่งผลให้กระบวนการเริ่มต้นใช้งานมีความราบรื่น หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับการตรวจสอบสิทธิ์แบบไม่ระบุตัวตน (และวิธีอัปเกรดเป็นบัญชีที่มีชื่อ) โปรดดูแนวทางปฏิบัติแนะนำสำหรับการตรวจสอบสิทธิ์แบบไม่ระบุชื่อ
- ในแผงด้านซ้ายของคอนโซล Firebase ให้คลิกสร้าง > การตรวจสอบสิทธิ์ จากนั้นคลิกเริ่มต้นใช้งาน
- ตอนนี้คุณอยู่ในแดชบอร์ดการตรวจสอบสิทธิ์แล้ว ซึ่งคุณจะดูผู้ใช้ที่ลงชื่อสมัครใช้ กำหนดค่าผู้ให้บริการการลงชื่อเข้าใช้ และจัดการการตั้งค่าได้
- เลือกแท็บวิธีการลงชื่อเข้าใช้ (หรือคลิกที่นี่เพื่อไปที่แท็บโดยตรง)
- คลิกไม่ระบุตัวตนจากตัวเลือกผู้ให้บริการ สลับสวิตช์เป็นเปิดใช้ แล้วคลิกบันทึก
ตั้งค่า Cloud Firestore
แอปพลิเคชัน Swift นี้ใช้ Cloud Firestore เพื่อบันทึกโน้ต วิธีตั้งค่า Cloud Firestore
- ในแผงด้านซ้ายของคอนโซล Firebase ให้คลิกสร้าง > ฐานข้อมูล Firestore จากนั้นคลิกสร้างฐานข้อมูล
- เลือกตำแหน่งสำหรับฐานข้อมูล ตรวจสอบว่าคุณเลือกสถานที่ที่ Gemini พร้อมใช้งาน (คุณสามารถใช้ us-central1) อย่างไรก็ตาม โปรดทราบว่าคุณไม่สามารถเปลี่ยนแปลงตำแหน่งนี้ในภายหลังได้ คลิกถัดไป
- เลือกตัวเลือกเริ่มในโหมดทดสอบ อ่านข้อจำกัดความรับผิดเกี่ยวกับกฎการรักษาความปลอดภัย โหมดทดสอบช่วยให้คุณเขียนไปยังฐานข้อมูลได้อย่างอิสระในระหว่างการพัฒนา
- คลิกสร้างเพื่อสร้างฐานข้อมูล
3. เชื่อมต่อแอปบนอุปกรณ์เคลื่อนที่
ในส่วนนี้ของ Codelab คุณจะดาวน์โหลดซอร์สโค้ดสำหรับแอปจดโน้ตแบบง่ายๆ และเชื่อมต่อกับโปรเจ็กต์ 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 คุณคลิกผ่านขั้นตอนการตั้งค่าที่เหลือได้แล้วโดยตัวอย่างที่คุณดาวน์โหลดในตอนต้นของส่วนนี้ได้ติดตั้ง Firebase Apple SDK ไว้แล้ว และการตั้งค่าการเริ่มต้น คุณสามารถดำเนินการให้เสร็จสิ้นได้โดยคลิกดำเนินการต่อในคอนโซล
เรียกใช้แอป
ได้เวลาลองใช้แอปแล้ว
- กลับไปที่ Xcode ให้เรียกใช้แอปบน iOS Simulator ในรายการแบบเลื่อนลงเรียกใช้ปลายทาง ให้เลือกเครื่องมือจำลอง iOS ก่อน
- จากนั้นคลิกปุ่มเรียกใช้ หรือกด ⌘ + R
- หลังจากเปิดแอปในเครื่องมือจำลองสำเร็จแล้ว ให้เพิ่มหมายเหตุอีก 2 ข้อ
- ในคอนโซล Firebase ให้ไปที่เบราว์เซอร์ข้อมูล Firestore เพื่อดูเอกสารใหม่ที่กำลังสร้างขึ้นขณะที่เพิ่มโน้ตใหม่ในแอป
4. ติดตั้ง Vector Search ที่มีส่วนขยาย Firestore
ในส่วนนี้ของ Codelab คุณจะติดตั้งส่วนขยาย Vector Search ที่มีส่วนขยาย Firestore และกำหนดค่าตามข้อกำหนดของแอปจดโน้ตที่คุณใช้งานอยู่
เริ่มติดตั้งส่วนขยาย
- คลิกแท็บส่วนขยายในส่วน Firestore
- คลิกสำรวจฮับส่วนขยาย
- พิมพ์ "เวกเตอร์"
- คลิกที่ "การค้นหาเวกเตอร์ที่มีส่วนขยาย Firestore"
ระบบจะนำคุณไปยังหน้ารายละเอียดของส่วนขยาย ซึ่งคุณจะอ่านเพิ่มเติมเกี่ยวกับส่วนขยาย วิธีการทำงาน บริการ Firebase ที่ต้องใช้ และวิธีกำหนดค่าส่วนขยายได้
- คลิกติดตั้งในคอนโซล Firebase
- ระบบจะแสดงรายการโปรเจ็กต์ของคุณทั้งหมด
- เลือกโปรเจ็กต์ที่คุณสร้างในขั้นตอนแรกของ Codelab นี้
กำหนดค่าส่วนขยาย
Firebase Extensions ใช้ประโยชน์จาก Cloud Functions for Firebase ซึ่งกำหนดให้โปรเจ็กต์ต้องอยู่ในแพ็กเกจ Blaze ในแบบจ่ายเมื่อใช้ ก่อนที่จะใช้ Vector Search กับส่วนขยาย Firestore คุณต้องอัปเกรดโปรเจ็กต์ก่อน
- คลิกอัปเกรดโปรเจ็กต์เพื่อดำเนินการต่อ
- เลือกบัญชีสำหรับการเรียกเก็บเงินที่มีอยู่ หรือสร้างบัญชีใหม่ คลิกต่อไป
- ตั้งงบประมาณ (เช่น 100 THB) คลิกต่อไป แล้วคลิกซื้อ
- ตรวจสอบว่าเปิดใช้ API และสร้างทรัพยากรแล้ว
- เปิดใช้บริการที่จำเป็น
- เมื่อเปิดใช้ Cloud Storage ให้เลือกโหมดทดสอบกฎความปลอดภัย
- ยืนยันว่า Cloud Storage จะใช้ตำแหน่งเดียวกับอินสแตนซ์ Cloud Firestore
- เมื่อเปิดใช้บริการทั้งหมดแล้ว ให้คลิก Next
- ตรวจสอบสิทธิ์เข้าถึงที่มอบให้ส่วนขยายนี้
- กำหนดค่าส่วนขยาย:
- เลือก Vertex AI เป็น LLM
- เส้นทางการรวบรวมข้อมูล: โน้ต
- ขีดจำกัดข้อความค้นหาเริ่มต้น: 3
- ชื่อช่องอินพุต: text
- ชื่อฟิลด์เอาต์พุต: การฝัง
- ชื่อช่องสถานะ:* *สถานะ*
- ฝังเอกสารที่มีอยู่: ใช่
- อัปเดตเอกสารที่มีอยู่: ใช่
- ตำแหน่งของ Cloud Function: us-central1
- คลิกติดตั้งส่วนขยายเพื่อดำเนินการติดตั้งให้เสร็จสิ้น
การดำเนินการนี้อาจใช้เวลาสักครู่ ในขณะที่คุณกำลังรอให้การติดตั้งเสร็จสมบูรณ์ คุณสามารถไปยังส่วนถัดไปของบทแนะนำ และอ่านข้อมูลพื้นฐานเกี่ยวกับการฝังเวกเตอร์
5. ความเป็นมา
ในขณะที่คุณกำลังรอให้การติดตั้งเสร็จสิ้น ต่อไปนี้เป็นข้อมูลพื้นฐานเกี่ยวกับวิธีการทำงานของการค้นหาเวกเตอร์ที่มีส่วนขยาย Firestore
เวกเตอร์ การฝัง และฐานข้อมูลเวกเตอร์คืออะไร
- เวกเตอร์คือวัตถุทางคณิตศาสตร์ที่แสดงขนาดและทิศทางของปริมาณ โดยสามารถใช้นำเสนอข้อมูลในลักษณะที่ทำให้เปรียบเทียบและค้นหาได้ง่ายขึ้น
- การฝังคือเวกเตอร์ที่แสดงความหมายของคำหรือวลี ซึ่งสร้างขึ้นด้วยการฝึกโครงข่ายประสาทบนคลังข้อความขนาดใหญ่และเรียนรู้ความสัมพันธ์ระหว่างคำ
- ฐานข้อมูลเวกเตอร์คือฐานข้อมูลที่ได้รับการเพิ่มประสิทธิภาพสำหรับการจัดเก็บและค้นหาข้อมูลเวกเตอร์ พารามิเตอร์เหล่านี้ช่วยให้สามารถค้นหาเพื่อนบ้านที่ใกล้ที่สุด ซึ่งเป็นกระบวนการค้นหาเวกเตอร์ที่คล้ายกันมากที่สุดกับเวกเตอร์การค้นหาหนึ่งๆ
การค้นหาเวกเตอร์ทำงานอย่างไร
การค้นหาเวกเตอร์ทำงานโดยการเปรียบเทียบเวกเตอร์ของข้อความค้นหากับเวกเตอร์ทั้งหมดในฐานข้อมูล เวกเตอร์ที่คล้ายกับเวกเตอร์ของข้อความค้นหามากที่สุดจะแสดงผลเป็นผลการค้นหา
ความคล้ายคลึงระหว่างเวกเตอร์ 2 เวกเตอร์สามารถวัดได้โดยใช้เมตริกระยะทางหลากหลายแบบ เมตริกระยะทางที่พบบ่อยที่สุดคือความคล้ายคลึงของโคไซน์ ซึ่งวัดมุมระหว่างเวกเตอร์ 2 เวกเตอร์
6. ลองใช้การค้นหาเวกเตอร์ที่มีส่วนขยาย Firestore
ก่อนที่จะใช้ส่วนขยาย Vector Search ที่มีส่วนขยาย Firestore ในแอป iOS ที่คุณดาวน์โหลดก่อนหน้านี้ใน Codelab คุณจะลองใช้ส่วนขยายได้ในคอนโซล Firebase
อ่านเอกสารประกอบ
Firebase Extensions มีเอกสารประกอบเกี่ยวกับวิธีการทํางาน
- เมื่อติดตั้งส่วนขยายเสร็จแล้ว ให้คลิกปุ่มเริ่มต้นใช้งาน
- ลองดูแท็บ "วิธีการทำงานของส่วนขยายนี้" ซึ่งให้ข้อมูลไว้ดังนี้
- วิธีประมวลผลการฝังสำหรับเอกสารด้วยการเพิ่มไปยังคอลเล็กชัน
notes
- วิธีค้นหาดัชนีโดยเรียกใช้ฟังก์ชันเรียกใช้ได้
ext-firestore-vector-search-queryCallable
- หรือวิธีค้นหาดัชนีโดยเพิ่มเอกสารการค้นหาลงในคอลเล็กชัน
_firestore-vector-search/index/queries
- นอกจากนี้ยังอธิบายวิธีตั้งค่าฟังก์ชันการฝังที่กำหนดเอง ซึ่งจะเป็นประโยชน์หากไม่มี LLM ที่ส่วนขยายรองรับที่ตรงกับความต้องการของคุณ และคุณต้องการใช้ LLM อื่นเพื่อประมวลผลการฝัง
- วิธีประมวลผลการฝังสำหรับเอกสารด้วยการเพิ่มไปยังคอลเล็กชัน
- คลิกลิงก์แดชบอร์ด Cloud Firestore เพื่อไปที่อินสแตนซ์ Firestore
- ไปที่เอกสาร
_firestore-vector-search/index
ส่วนขยายน่าจะประมวลผลการฝังสำหรับเอกสารโน้ตทั้งหมดที่สร้างไว้ในขั้นตอนก่อนหน้าใน Codelab นี้เสร็จเรียบร้อยแล้ว - หากต้องการยืนยัน ให้เปิดเอกสารโน้ตรายการใดรายการหนึ่ง แล้วคุณจะเห็นช่องเพิ่มเติมชื่อ
embedding
ประเภทvector<768>
และช่องstatus
สร้างเอกสารตัวอย่าง
คุณสามารถสร้างเอกสารใหม่ในคอนโซล Firebase เพื่อดูการทำงานของส่วนขยายได้
- ยังอยู่ในเบราว์เซอร์ข้อมูล Firestore ให้ไปที่คอลเล็กชัน
notes
แล้วคลิก + เพิ่มเอกสารในคอลัมน์กลาง - คลิกรหัสอัตโนมัติเพื่อสร้างรหัสเอกสารใหม่ที่ไม่ซ้ำกัน
- เพิ่มฟิลด์ชื่อ
text
ของประเภทสตริง และวางข้อความบางส่วนลงในช่อง value ซึ่งจะต้องไม่ใช่ lorem ipsum หรือข้อความสุ่มอื่นๆ เช่น เลือกบทความข่าว เป็นต้น - คลิกบันทึก
- สังเกตวิธีที่ส่วนขยายเพิ่มช่องสถานะเพื่อระบุว่ากำลังประมวลผลข้อมูล
- หลังจากนั้นสักครู่ คุณจะเห็นช่อง
embedding
ใหม่ที่มีค่าvector<768>
ดำเนินการค้นหา
ส่วนขยายการค้นหาเวกเตอร์ที่มี Firestore มีฟีเจอร์เล็กน้อยที่ช่วยให้คุณค้นหาดัชนีเอกสารได้โดยไม่ต้องเชื่อมต่อแอป
- ในส่วน Firestore ของคอนโซล Firebase ให้ไปที่เอกสาร
_firestore-vector-search/index
- คลิกที่ + เริ่มต้นคอลเล็กชัน
- สร้างคอลเล็กชันย่อยใหม่ชื่อ
queries
- สร้างเอกสารใหม่และตั้งค่าช่อง
query
เป็นข้อความที่ปรากฏในเอกสารของคุณ ซึ่งวิธีนี้เหมาะสำหรับการค้นหาเชิงความหมาย เช่น "ฉันจะแมปเอกสาร Firestore กับ Swift ได้อย่างไร" (หากโน้ตที่คุณเพิ่มอย่างน้อย 1 รายการมีข้อความที่กล่าวถึงหัวข้อนี้) - คุณอาจเห็นข้อผิดพลาดในสถานะ
- เนื่องจากไม่มีดัชนี หากต้องการกำหนดค่าดัชนีที่ขาดหายไป ให้ไปที่คอนโซล Google Cloud ของโปรเจ็กต์โดยไปที่ลิงก์นี้ แล้วเลือกโปรเจ็กต์จากรายการ
- ใน Cloud Log Explorer คุณควรเห็นข้อความแสดงข้อผิดพลาด "FAILED_PRECONDITION: ไม่มีการกำหนดค่าดัชนีเวกเตอร์ โปรดสร้างดัชนีที่จำเป็นด้วยคำสั่ง gcloud ต่อไปนี้: ..."
- ข้อความแสดงข้อผิดพลาดยังมีคำสั่ง
gcloud
ที่คุณต้องเรียกใช้เพื่อกำหนดค่าดัชนีที่ขาดหายไปด้วย - เรียกใช้คำสั่งต่อไปนี้จากบรรทัดคำสั่ง หากยังไม่ได้ติดตั้ง
gcloud
CLI ในเครื่อง ให้ทำตามวิธีการที่นี่เพื่อติดตั้ง
การสร้างดัชนีจะใช้เวลา 2-3 นาที คุณตรวจสอบความคืบหน้าได้ในแท็บดัชนีในส่วน Firestore ของคอนโซล Firebasegcloud 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
- เมื่อตั้งค่าดัชนีแล้ว คุณจะสร้างเอกสารการค้นหาใหม่ได้
- คุณจะเห็นรายการรหัสเอกสารที่ตรงกันในช่องผลลัพธ์
- คัดลอกรหัส 1 รายการและกลับไปที่คอลเล็กชัน
notes
- ใช้ ⌘+F เพื่อค้นหารหัสเอกสารที่คุณคัดลอก เอกสารนี้คือรหัสที่ตรงกับการค้นหาของคุณมากที่สุด
7. ใช้การค้นหาเชิงความหมาย
ในที่สุดถึงเวลาเชื่อมต่อแอปบนอุปกรณ์เคลื่อนที่เข้ากับส่วนขยาย Vector Search ที่มีส่วนขยาย Firestore และนำฟีเจอร์การค้นหาเชิงความหมายมาใช้เพื่อให้ผู้ใช้ค้นหาโน้ตโดยใช้คำค้นหาที่เป็นภาษาธรรมชาติ
เชื่อมต่อฟังก์ชันที่เรียกได้เพื่อดำเนินการค้นหา
ส่วนขยาย Vector Search ที่มี Firestore มี Cloud Function ที่คุณเรียกใช้จากแอปบนอุปกรณ์เคลื่อนที่เพื่อค้นหาดัชนีที่สร้างไว้ก่อนหน้านี้ใน Codelab นี้ได้ ในขั้นตอนนี้ คุณจะสร้างการเชื่อมต่อระหว่างแอปบนอุปกรณ์เคลื่อนที่และฟังก์ชันที่เรียกใช้ได้นี้ Swift SDK ของ Firebase มี API ที่ทำให้การเรียกใช้จากทางไกลเป็นไปอย่างราบรื่น
- กลับไปที่ Xcode และตรวจสอบว่าคุณอยู่ในโปรเจ็กต์ที่โคลนในขั้นตอนก่อนหน้าใน Codelab นี้
- เปิดไฟล์
NotesRepository.swift
- ค้นหาบรรทัดที่มี
private lazy var vectorSearchQueryCallable: Callable
= functions.httpsCallable("")
หากต้องการเรียกใช้ Cloud Function ที่เรียกใช้ได้ คุณต้องระบุชื่อของฟังก์ชันที่ต้องการเรียกใช้
- ไปที่คอนโซล Firebase ของโปรเจ็กต์ และเปิดรายการในเมนูฟังก์ชันในส่วนสร้าง
- คุณจะเห็นรายการฟังก์ชันที่ส่วนขยายติดตั้งไว้
- ค้นหารายการที่ชื่อ
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 [] } }
เชื่อมต่อ UI
หากต้องการอนุญาตให้ผู้ใช้ค้นหาโน้ต คุณจะต้องใช้แถบค้นหาในหน้าจอรายการบันทึก เมื่อผู้ใช้พิมพ์ข้อความค้นหา คุณจะต้องเรียกใช้เมธอด performQuery
ที่คุณนำไปใช้ในขั้นตอนก่อนหน้า การใช้ตัวปรับแต่งการแสดงผล searchable
และ task
จาก SwiftUI ทำให้ใช้โค้ดเพียง 2-3 บรรทัดเท่านั้น
- ขั้นแรก เปิด
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
- คุณจะเห็นโน้ตเดียวกับที่เพิ่มในแอปก่อนหน้านี้ใน Codelab นี้ รวมถึงโน้ตที่เพิ่มผ่านคอนโซล Firebase
- คุณควรเห็นช่องค้นหาที่ด้านบนของรายการโน้ต
- พิมพ์คำที่ปรากฏในเอกสารที่คุณเพิ่ม วิธีนี้เหมาะสำหรับการค้นหาเชิงความหมาย เช่น "ฉันจะเรียกใช้ Firebase API แบบไม่พร้อมกันจาก Swift ได้อย่างไร" (หากโน้ตที่คุณเพิ่มอย่างน้อย 1 รายการมีข้อความที่กล่าวถึงหัวข้อนี้)
- คุณอาจคาดหวังว่าจะเห็นผลการค้นหา แต่มุมมองรายการกลับว่างเปล่า และคอนโซล Xcode แสดงข้อความแสดงข้อผิดพลาดว่า "มีการเรียกฟังก์ชันด้วยอาร์กิวเมนต์ที่ไม่ถูกต้อง"
หมายความว่าคุณส่งข้อมูลในรูปแบบที่ไม่ถูกต้อง
วิเคราะห์ข้อความแสดงข้อผิดพลาด
- หากต้องการดูปัญหาที่เกิดขึ้น ให้ไปที่คอนโซล Firebase
- ไปที่ส่วนฟังก์ชัน
- ค้นหาฟังก์ชัน
ext-firestore-vector-search-queryCallable
เปิดเมนูรายการเพิ่มเติมโดยคลิกที่จุดแนวตั้ง 3 จุด - เลือกดูบันทึกเพื่อไปที่เครื่องมือสำรวจบันทึก
- คุณควรจะเห็นข้อผิดพลาด
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. ยินดีด้วย
ยินดีด้วย ทำ Codelab นี้สำเร็จแล้ว
คุณได้เรียนรู้วิธีต่อไปนี้ใน Codelab
- ตั้งค่าฐานข้อมูล Cloud Firestore ที่เปิดใช้การค้นหาเชิงความหมาย
- สร้างแอป SwiftUI แบบง่ายเพื่อโต้ตอบกับฐานข้อมูล
- ใช้งานแถบค้นหาโดยใช้ตัวแก้ไขมุมมองที่ค้นหาได้ของ SwiftUI และตัวปรับแต่งงาน
- เรียกใช้ Cloud Function เพื่อค้นหาแบบความหมายในฐานข้อมูลโดยใช้อินเทอร์เฟซ Callable ของ Firestore SDK
ด้วยความรู้ที่ได้รับจาก Codelab นี้ คุณจึงสามารถสร้างแอปพลิเคชันที่มีประสิทธิภาพซึ่งใช้ประโยชน์จากความสามารถในการค้นหาเชิงความหมายของ Cloud Firestore เพื่อมอบประสบการณ์การค้นหาที่ใช้งานง่ายและมีประสิทธิภาพยิ่งขึ้นให้แก่ผู้ใช้
ดูข้อมูลเพิ่มเติมเกี่ยวกับฟิลด์เวกเตอร์ใหม่ของ Firestore และวิธีประมวลผลการฝังเวกเตอร์ได้ในเอกสารประกอบ