1. ภาพรวม
ใน Codelab นี้ คุณจะได้เรียนรู้วิธีเพิ่มฟีเจอร์การค้นหาที่มีประสิทธิภาพลงในแอปโดยใช้การค้นหาความคล้ายคลึงกันของเวกเตอร์ของ Firestore คุณจะใช้ฟีเจอร์การค้นหาเชิงความหมายสําหรับแอปจดบันทึกที่เขียนด้วย Swift และ SwiftUI
สิ่งที่คุณจะได้เรียนรู้
- วิธีติดตั้งการค้นหาเวกเตอร์ด้วยส่วนขยาย Firestore เพื่อคํานวณการฝังเวกเตอร์
- วิธีเรียกใช้ Firebase Cloud Functions จากแอปพลิเคชัน Swift
- วิธีกรองข้อมูลล่วงหน้าตามผู้ใช้ที่ลงชื่อเข้าใช้
สิ่งที่ต้องมี
- Xcode 15.3
- โค้ดตัวอย่างของ Codelab คุณจะดาวน์โหลดไฟล์นี้ในขั้นตอนถัดไปของโค้ดแล็บ
2. สร้างและตั้งค่าโปรเจ็กต์ Firebase
ในการใช้ส่วนขยาย Firebase Vector Search คุณต้องมีโปรเจ็กต์ Firebase ในส่วนนี้ของโค้ดแล็บ คุณจะได้สร้างโปรเจ็กต์ Firebase ใหม่ และเปิดใช้งานบริการที่จําเป็น เช่น Cloud Firestore และ Firebase Authentication
สร้างโปรเจ็กต์ Firebase
- ลงชื่อเข้าใช้ Firebase
- ในคอนโซล Firebase ให้คลิกเพิ่มโปรเจ็กต์ แล้วตั้งชื่อโปรเจ็กต์เป็น Firestore Vector Search Lab
- คลิกตัวเลือกการสร้างโปรเจ็กต์ ยอมรับข้อกำหนดของ Firebase หากได้รับข้อความแจ้ง
- ในหน้าจอ Google Analytics ให้ยกเลิกการเลือกช่องเปิดใช้ Google Analytics สําหรับโปรเจ็กต์นี้ เนื่องจากคุณจะไม่ได้ใช้ Analytics สําหรับแอปนี้
- สุดท้าย ให้คลิกสร้างโปรเจ็กต์
ดูข้อมูลเพิ่มเติมเกี่ยวกับโปรเจ็กต์ Firebase ได้ที่ทําความเข้าใจโปรเจ็กต์ Firebase
อัปเกรดแพ็กเกจราคา Firebase
หากต้องการใช้ Firebase Extensions และบริการระบบคลาวด์ที่เกี่ยวข้อง โปรเจ็กต์ Firebase ของคุณจะต้องอยู่ในแพ็กเกจราคาแบบชําระเงินตามการใช้งาน (Blaze) ซึ่งหมายความว่าโปรเจ็กต์จะลิงก์กับบัญชีการเรียกเก็บเงินในระบบคลาวด์
- บัญชีการเรียกเก็บเงินระบบคลาวด์ต้องมีวิธีการชำระเงิน เช่น บัตรเครดิต
- หากคุณเพิ่งเริ่มใช้ Firebase และ Google Cloud ให้ตรวจสอบว่าคุณมีสิทธิ์รับเครดิตมูลค่า $300 และบัญชีการเรียกเก็บเงินระบบคลาวด์แบบทดลองใช้ฟรีหรือไม่
- หากคุณทำ Codelab นี้เป็นส่วนหนึ่งของกิจกรรม โปรดสอบถามผู้จัดว่ามีเครดิต Cloud เหลืออยู่ไหม
หากต้องการอัปเกรดโปรเจ็กต์เป็นแพ็กเกจ Blaze ให้ทำตามขั้นตอนต่อไปนี้
- ในคอนโซล Firebase ให้เลือกอัปเกรดแพ็กเกจ
- เลือกแพ็กเกจ Blaze ทำตามวิธีการบนหน้าจอเพื่อลิงก์บัญชีสำหรับการเรียกเก็บเงินใน Cloud กับโปรเจ็กต์
หากจำเป็นต้องสร้างบัญชีสำหรับการเรียกเก็บเงินใน Cloud เป็นส่วนหนึ่งของการอัปเกรดนี้ คุณอาจต้องกลับไปที่ขั้นตอนการอัปเกรดในคอนโซล Firebase เพื่อดำเนินการอัปเกรดให้เสร็จสมบูรณ์
เปิดใช้และตั้งค่าผลิตภัณฑ์ Firebase ในคอนโซล
แอปที่คุณกําลังสร้างใช้ผลิตภัณฑ์ Firebase หลายรายการที่พร้อมให้บริการสําหรับแอป Apple ดังนี้
- การตรวจสอบสิทธิ์ของ Firebase เพื่อให้ผู้ใช้ลงชื่อเข้าใช้แอปได้ง่ายๆ
- Cloud Firestore เพื่อบันทึก Structured Data ในระบบคลาวด์และรับการแจ้งเตือนทันทีเมื่อมีการเปลี่ยนแปลงข้อมูล
- กฎการรักษาความปลอดภัยของ Firebase เพื่อรักษาความปลอดภัยให้ฐานข้อมูล
ผลิตภัณฑ์เหล่านี้บางรายการต้องมีการกำหนดค่าพิเศษหรือต้องเปิดใช้โดยใช้คอนโซล Firebase
เปิดใช้การตรวจสอบสิทธิ์แบบไม่ระบุชื่อสําหรับการตรวจสอบสิทธิ์ Firebase
แอปพลิเคชันนี้ใช้การตรวจสอบสิทธิ์แบบไม่ระบุชื่อเพื่อให้ผู้ใช้เริ่มใช้แอปได้โดยไม่ต้องสร้างบัญชีก่อน ซึ่งทำให้กระบวนการเริ่มต้นใช้งานเป็นไปอย่างราบรื่น ดูข้อมูลเพิ่มเติมเกี่ยวกับการตรวจสอบสิทธิ์แบบไม่ระบุชื่อ (และวิธีอัปเกรดเป็นบัญชีที่มีชื่อ) ได้ที่แนวทางปฏิบัติแนะนำสำหรับการตรวจสอบสิทธิ์แบบไม่ระบุชื่อ
- ในแผงด้านซ้ายของคอนโซล Firebase ให้คลิก Build > Authentication จากนั้นคลิกเริ่มต้นใช้งาน
- ตอนนี้คุณอยู่ในแดชบอร์ดการตรวจสอบสิทธิ์ ซึ่งคุณสามารถดูผู้ใช้ที่ลงชื่อสมัครใช้ กำหนดค่าผู้ให้บริการลงชื่อเข้าใช้ และจัดการการตั้งค่าได้
- เลือกแท็บวิธีการลงชื่อเข้าใช้ (หรือคลิกที่นี่เพื่อไปที่แท็บโดยตรง)
- คลิกไม่ระบุตัวตนจากตัวเลือกผู้ให้บริการ สลับสวิตช์เป็นเปิดใช้ แล้วคลิกบันทึก
ตั้งค่า Cloud Firestore
แอปพลิเคชัน Swift นี้ใช้ Cloud Firestore เพื่อบันทึกโน้ต
วิธีตั้งค่า Cloud Firestore ในโปรเจ็กต์ Firebase มีดังนี้
- ในแผงด้านซ้ายของคอนโซล Firebase ให้ขยายสร้าง แล้วเลือกฐานข้อมูล Firestore
- คลิกสร้างฐานข้อมูล
- ตั้งค่ารหัสฐานข้อมูลเป็น
(default)
- เลือกตำแหน่งของฐานข้อมูล แล้วคลิกถัดไป
สำหรับแอปจริง คุณจะต้องเลือกตำแหน่งที่ใกล้กับผู้ใช้ - คลิกเริ่มในโหมดทดสอบ อ่านข้อจำกัดความรับผิดเกี่ยวกับกฎการรักษาความปลอดภัย
ในภายหลังในโค้ดแล็บนี้ คุณจะเพิ่มกฎการรักษาความปลอดภัยเพื่อรักษาความปลอดภัยให้กับข้อมูล อย่าเผยแพร่หรือแสดงแอปต่อสาธารณะโดยไม่เพิ่มกฎความปลอดภัยสําหรับฐานข้อมูล - คลิกสร้าง
ตั้งค่า Cloud Storage สำหรับ Firebase
เว็บแอปใช้ Cloud Storage for Firebase เพื่อจัดเก็บ อัปโหลด และแชร์รูปภาพ
วิธีตั้งค่า Cloud Storage for 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)
- คุณสามารถป้อนชื่อเล่นแอป (Notes for iOS) ได้หากต้องการ
- คลิก "ลงทะเบียนแอป" เพื่อไปยังขั้นตอนถัดไป
- ดาวน์โหลดไฟล์ GoogleServices-Info.plist
- ลาก GoogleServices-Info.plist ลงในโฟลเดอร์ Notes ของโปรเจ็กต์ Xcode วิธีที่ดีในการทำเช่นนี้คือการวางไว้ใต้ไฟล์ Assets.xcassets
- เลือกคัดลอกรายการหากจําเป็น ตรวจสอบว่าได้เลือกเป้าหมายหมายเหตุในเพิ่มลงในเป้าหมาย แล้วคลิกเสร็จสิ้น
- ในคอนโซล Firebase คุณจะคลิกผ่านขั้นตอนการตั้งค่าที่เหลือได้ เช่น ตัวอย่างที่คุณดาวน์โหลดในตอนต้นของส่วนนี้มี Firebase Apple SDK ติดตั้งอยู่แล้ว รวมถึงการตั้งค่าการเริ่มต้น คุณดำเนินการให้เสร็จสิ้นได้โดยคลิกดำเนินการต่อไปยังคอนโซล
เรียกใช้แอป
ตอนนี้ถึงเวลาลองใช้แอปแล้ว
- กลับไปที่ Xcode แล้วเรียกใช้แอปในโปรแกรมจำลอง iOS ในเมนูแบบเลื่อนลงปลายทางการเรียกใช้ ให้เลือกโปรแกรมจำลอง iOS รายการใดรายการหนึ่งก่อน
- จากนั้นคลิกปุ่มเรียกใช้ หรือกด ⌘ + R
- เมื่อแอปเปิดใช้งานบนเครื่องจำลองเรียบร้อยแล้ว ให้เพิ่มหมายเหตุ 2-3 รายการ
- ในคอนโซล Firebase ให้ไปที่เครื่องมือเรียกดูข้อมูล Firestore เพื่อให้คุณเห็นเอกสารใหม่ที่กำลังสร้างขึ้นเมื่อเพิ่มโน้ตใหม่ในแอป
4. ติดตั้งส่วนขยายการค้นหาเวกเตอร์ด้วย Firestore
ในส่วนนี้ของโค้ดแล็บ คุณจะติดตั้งส่วนขยายการค้นหาเวกเตอร์ด้วย Firestore และกำหนดค่าตามข้อกำหนดของแอปจดบันทึกที่คุณกำลังพัฒนา
เริ่มติดตั้งส่วนขยาย
- ขณะยังอยู่ในส่วน Firestore ให้คลิกแท็บส่วนขยาย
- คลิกสำรวจฮับส่วนขยาย
- พิมพ์ "เวกเตอร์"
- คลิก "การค้นหาเวกเตอร์ด้วยส่วนขยาย Firestore" ซึ่งจะนำคุณไปยังหน้ารายละเอียดของส่วนขยาย ซึ่งคุณสามารถอ่านข้อมูลเพิ่มเติมเกี่ยวกับส่วนขยาย วิธีการทำงานของส่วนขยาย บริการ Firebase ที่จำเป็น และวิธีกำหนดค่าส่วนขยาย
- คลิกติดตั้งในคอนโซล Firebase
- คุณจะเห็นรายการโปรเจ็กต์ทั้งหมด
- เลือกโปรเจ็กต์ที่คุณสร้างในขั้นตอนแรกของ Codelab นี้
กําหนดค่าส่วนขยาย
- ตรวจสอบการเปิดใช้ API และสร้างทรัพยากร
- เปิดใช้บริการที่จำเป็น
- เมื่อเปิดใช้บริการทั้งหมดแล้ว ให้คลิกถัดไป
- ตรวจสอบสิทธิ์เข้าถึงที่มอบให้ส่วนขยายนี้
- กําหนดค่าส่วนขยาย
- เลือก Vertex AI เป็น LLM
- เส้นทางคอลเล็กชัน: notes
- ขีดจำกัดการค้นหาเริ่มต้น: 3
- ชื่อช่องสำหรับป้อนข้อมูล: text
- ชื่อช่องเอาต์พุต: embedding
- ชื่อช่องสถานะ:* *status*
- ฝังเอกสารที่มีอยู่: ใช่
- อัปเดตเอกสารที่มีอยู่: ใช่
- ตำแหน่ง Cloud Function: us-central1
- คลิกติดตั้งส่วนขยายเพื่อดำเนินการติดตั้งให้เสร็จสิ้น
การดำเนินการนี้อาจใช้เวลาสักครู่ ขณะรอให้การติดตั้งเสร็จสมบูรณ์ คุณสามารถข้ามไปยังส่วนถัดไปของบทแนะนําและอ่านข้อมูลเบื้องต้นเกี่ยวกับเวกเตอร์เชิงลึกได้
5. ข้อมูลเบื้องต้น
ขณะรอให้การติดตั้งเสร็จสมบูรณ์ ต่อไปนี้เป็นข้อมูลเบื้องต้นเกี่ยวกับวิธีการทำงานของการค้นหาด้วยเวกเตอร์ด้วยส่วนขยาย Firestore
ฐานข้อมูลเวกเตอร์ การฝัง และฐานข้อมูลเวกเตอร์คืออะไร
- เวกเตอร์เป็นวัตถุทางคณิตศาสตร์ที่แสดงขนาดและทิศทางของจำนวน สามารถใช้เพื่อแสดงข้อมูลในลักษณะที่ทําให้เปรียบเทียบและค้นหาได้ง่ายขึ้น
- การฝังคือเวกเตอร์ที่แสดงถึงความหมายของคำหรือวลี โดยสร้างขึ้นจากการฝึกโครงข่ายระบบประสาทเทียมด้วยชุดข้อความขนาดใหญ่และเรียนรู้ความสัมพันธ์ระหว่างคำ
- ฐานข้อมูลเวกเตอร์เป็นฐานข้อมูลที่ได้รับการเพิ่มประสิทธิภาพสำหรับการจัดเก็บและค้นหาข้อมูลเวกเตอร์ ทำให้ค้นหาเพื่อนบ้านที่อยู่ใกล้ที่สุดได้อย่างมีประสิทธิภาพ ซึ่งเป็นกระบวนการหาเวกเตอร์ที่คล้ายกับเวกเตอร์ของคำค้นหามากที่สุด
การทำงานการค้นหาเวกเตอร์
การค้นหาเวกเตอร์ทำงานโดยการเปรียบเทียบเวกเตอร์การค้นหากับเวกเตอร์ทั้งหมดในฐานข้อมูล เวกเตอร์ที่คล้ายกับเวกเตอร์การค้นหามากที่สุดจะแสดงผลเป็นผลการค้นหา
ความคล้ายคลึงกันระหว่างเวกเตอร์ 2 รายการสามารถวัดได้โดยใช้เมตริกระยะทางที่หลากหลาย เมตริกระยะทางที่ใช้กันมากที่สุดคือความคล้ายคลึงของโคไซน์ ซึ่งจะวัดมุมระหว่างเวกเตอร์ 2 รายการ
6. ลองใช้การค้นหาเวกเตอร์ด้วยส่วนขยาย Firestore
ก่อนใช้การค้นหาเวกเตอร์ด้วยส่วนขยาย Firestore ในแอป iOS ที่คุณดาวน์โหลดไว้ก่อนหน้านี้ในโค้ดแล็บนี้ คุณสามารถลองใช้ส่วนขยายในคอนโซล Firebase ได้
อ่านเอกสารประกอบ
Firebase Extensions มีเอกสารประกอบเกี่ยวกับวิธีการทํางาน
- เมื่อติดตั้งส่วนขยายเสร็จแล้ว ให้คลิกปุ่มเริ่มต้นใช้งาน
- โปรดดูแท็บ "วิธีการทำงานของส่วนขยายนี้" ซึ่งจะอธิบายข้อมูลต่อไปนี้
- วิธีประมวลผลการฝังสำหรับเอกสารโดยการเพิ่มไปยังคอลเล็กชัน
notes
- วิธีค้นหาดัชนีโดยการเรียกใช้
ext-firestore-vector-search-queryCallable
ฟังก์ชันที่เรียกใช้ได้ - หรือวิธีค้นหาดัชนีโดยเพิ่มเอกสารการค้นหาลงในคอลเล็กชัน
_firestore-vector-search/index/queries
- นอกจากนี้ ยังอธิบายวิธีตั้งค่าฟังก์ชันการฝังที่กำหนดเอง ซึ่งมีประโยชน์ในกรณีที่ LLM ทั้งหมดที่ส่วนขยายรองรับไม่ตรงกับข้อกำหนดของคุณ และคุณต้องการใช้ LLM อื่นเพื่อคํานวณการฝัง
- วิธีประมวลผลการฝังสำหรับเอกสารโดยการเพิ่มไปยังคอลเล็กชัน
- คลิกลิงก์แดชบอร์ด Cloud Firestore เพื่อไปยังอินสแตนซ์ Firestore
- ไปที่เอกสาร
_firestore-vector-search/index
ซึ่งควรแสดงว่าส่วนขยายได้ประมวลผลการฝังสําหรับเอกสารโน้ตทั้งหมดที่คุณสร้างในขั้นตอนก่อนหน้าในโค้ดแล็บนี้แล้ว - หากต้องการยืนยัน ให้เปิดเอกสารโน้ตรายการใดรายการหนึ่ง แล้วคุณจะเห็นช่องเพิ่มเติมชื่อ
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 สําหรับโปรเจ็กต์โดยไปที่ลิงก์นี้ แล้วเลือกโปรเจ็กต์จากรายการ
- ใน Logs Explorer ของ Cloud คุณควรเห็นข้อความแสดงข้อผิดพลาด "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
- เมื่อตั้งค่าดัชนีแล้ว คุณสามารถสร้างเอกสารการค้นหาใหม่ได้
- ตอนนี้คุณควรเห็นรายการรหัสเอกสารที่ตรงกันในช่องผลลัพธ์
- คัดลอกรหัสใดรหัสหนึ่ง แล้วกลับไปที่คอลเล็กชัน
notes
- ใช้ ⌘+F เพื่อค้นหารหัสเอกสารที่คุณคัดลอก เอกสารนี้เป็นเอกสารที่ตรงกับคำค้นหาของคุณมากที่สุด
7. ใช้การค้นหาเชิงความหมาย
ตอนนี้ถึงเวลาเชื่อมต่อแอปบนอุปกรณ์เคลื่อนที่กับ Vector Search ด้วยส่วนขยาย Firestore และใช้งานฟีเจอร์การค้นหาเชิงความหมายที่จะช่วยให้ผู้ใช้ค้นหาโน้ตโดยใช้การค้นหาด้วยภาษาที่เป็นธรรมชาติ
เชื่อมต่อฟังก์ชันที่เรียกใช้ได้สําหรับการค้นหา
การค้นหา Vector Search ด้วยส่วนขยาย Firestore มี Cloud Function ที่คุณเรียกใช้จากแอปบนอุปกรณ์เคลื่อนที่เพื่อค้นหาดัชนีที่สร้างไว้ก่อนหน้านี้ใน Codelab ได้ ในขั้นตอนนี้ คุณจะต้องสร้างการเชื่อมต่อระหว่างแอปบนอุปกรณ์เคลื่อนที่กับฟังก์ชันที่เรียกใช้ได้นี้ Swift SDK ของ Firebase มี API ที่ทำให้การเรียกใช้ฟังก์ชันระยะไกลเป็นไปอย่างราบรื่น
- กลับไปที่ Xcode และตรวจสอบว่าคุณอยู่ในโปรเจ็กต์ที่คุณโคลนในขั้นตอนก่อนหน้าในโค้ดแล็บนี้
- เปิดไฟล์
NotesRepository.swift
- ค้นหาบรรทัดที่มี
private lazy var vectorSearchQueryCallable: Callable
= functions.httpsCallable("")
หากต้องการเรียกใช้ Cloud Function ที่เรียกใช้ได้ คุณต้องระบุชื่อของฟังก์ชันที่ต้องการเรียก
- ไปที่คอนโซล Firebase ของโปรเจ็กต์ แล้วเปิดรายการเมนู Functions ในส่วน Build
- คุณจะเห็นรายการฟังก์ชันที่ส่วนขยายติดตั้งไว้
- ค้นหารายการที่ชื่อ
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 บรรทัดเท่านั้น
- ขั้นแรก ให้เปิด
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 (หรือคลิกปุ่ม Run) เพื่อเปิดแอปในเครื่องจำลอง iOS
- คุณควรเห็นโน้ตเดียวกันกับที่เพิ่มในแอปก่อนหน้านี้ในโค้ดแล็บนี้ รวมถึงโน้ตที่คุณเพิ่มผ่านคอนโซล 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 นี้เสร็จสมบูรณ์
ในโค้ดแล็บนี้ คุณได้เรียนรู้วิธีทำสิ่งต่อไปนี้
- ตั้งค่าฐานข้อมูล Cloud Firestore ที่เปิดใช้การค้นหาเชิงความหมาย
- สร้างแอป SwiftUI ง่ายๆ เพื่อโต้ตอบกับฐานข้อมูล
- ใช้แถบค้นหาโดยใช้ตัวแก้ไขมุมมองที่ค้นหาได้และตัวแก้ไขงานของ SwiftUI
- เรียกใช้ Cloud Function เพื่อค้นหาเชิงความหมายในฐานข้อมูลโดยใช้อินเทอร์เฟซ Callable ของ Firestore SDK
ความรู้ที่ได้รับในโค้ดแล็บนี้จะช่วยให้คุณสร้างแอปพลิเคชันที่มีประสิทธิภาพซึ่งใช้ประโยชน์จากความสามารถในการค้นหาเชิงความหมายของ Cloud Firestore เพื่อมอบประสบการณ์การค้นหาที่ใช้งานง่ายและมีประสิทธิภาพมากขึ้นให้แก่ผู้ใช้
ดูข้อมูลเพิ่มเติมเกี่ยวกับช่องเวกเตอร์ใหม่ของ Firestore และวิธีประมวลผลการฝังเวกเตอร์ได้ในเอกสารประกอบ