1. ภาพรวม
ในโค้ดแล็บนี้ คุณจะได้เรียนรู้วิธีเพิ่มฟีเจอร์การค้นหาที่มีประสิทธิภาพลงในแอปโดยใช้การค้นหาความคล้ายกันของเวกเตอร์ใน Firestore คุณจะใช้ฟีเจอร์การค้นหาเชิงความหมายสำหรับแอปจดบันทึกที่เขียนด้วย Swift และ SwiftUI
สิ่งที่คุณจะได้เรียนรู้
- วิธีติดตั้งส่วนขยายการค้นหาเวกเตอร์ด้วย Firestore เพื่อคำนวณการฝังเวกเตอร์
- วิธีเรียกใช้ Firebase Cloud Functions จากแอปพลิเคชัน Swift
- วิธีกรองข้อมูลล่วงหน้าตามผู้ใช้ที่ลงชื่อเข้าใช้
สิ่งที่คุณจะต้องมี
- Xcode 15.3
- โค้ดตัวอย่างของ Codelab คุณจะดาวน์โหลดได้ในขั้นตอนถัดไปของโค้ดแล็บ
2. สร้างและตั้งค่าโปรเจ็กต์ Firebase
คุณต้องมีโปรเจ็กต์ Firebase จึงจะใช้ส่วนขยายการค้นหาเวกเตอร์ของ Firebase ได้ ในส่วนนี้ของโค้ดแล็บ คุณจะสร้างโปรเจ็กต์ Firebase ใหม่และเปิดใช้งานบริการที่จำเป็น เช่น Cloud Firestore และ Firebase Authentication
สร้างโปรเจ็กต์ Firebase
- ลงชื่อเข้าใช้คอนโซล Firebase โดยใช้บัญชี Google
- คลิกปุ่มเพื่อสร้างโปรเจ็กต์ใหม่ แล้วป้อนชื่อโปรเจ็กต์ (เช่น
Firestore Vector Search Codelab
)
- คลิกต่อไป
- หากได้รับแจ้ง ให้อ่านและยอมรับข้อกำหนดของ Firebase แล้วคลิกต่อไป
- (ไม่บังคับ) เปิดใช้ความช่วยเหลือจาก AI ในคอนโซล Firebase (เรียกว่า "Gemini ใน Firebase")
- สำหรับ Codelab นี้ คุณไม่จำเป็นต้องใช้ Google Analytics ดังนั้นให้ปิดตัวเลือก Google Analytics
- คลิกสร้างโปรเจ็กต์ รอให้ระบบจัดสรรโปรเจ็กต์ แล้วคลิกดำเนินการต่อ
ดูข้อมูลเพิ่มเติมเกี่ยวกับโปรเจ็กต์ Firebase ได้ที่ทําความเข้าใจโปรเจ็กต์ Firebase
อัปเกรดแพ็กเกจราคาของ Firebase
หากต้องการใช้ Firebase Extensions และบริการระบบคลาวด์ที่เกี่ยวข้อง โปรเจ็กต์ Firebase ของคุณต้องอยู่ในแพ็กเกจราคาแบบจ่ายตามการใช้งาน (Blaze) ซึ่งหมายความว่าโปรเจ็กต์ต้องลิงก์กับบัญชีการเรียกเก็บเงินใน Cloud
- บัญชีสำหรับการเรียกเก็บเงินของ Cloud ต้องมีวิธีการชำระเงิน เช่น บัตรเครดิต
- หากเพิ่งเริ่มใช้ Firebase และ Google Cloud โปรดตรวจสอบว่าคุณมีสิทธิ์รับเครดิต$300 และบัญชีสำหรับการเรียกเก็บเงินในระบบคลาวด์แบบทดลองใช้ฟรีหรือไม่
- หากคุณกำลังทำ Codelab นี้เป็นส่วนหนึ่งของกิจกรรม โปรดสอบถามผู้จัดว่ามีเครดิต Cloud ให้หรือไม่
หากต้องการอัปเกรดโปรเจ็กต์เป็นแพ็กเกจ Blaze ให้ทำตามขั้นตอนต่อไปนี้
- ในคอนโซล Firebase ให้เลือกอัปเกรดแพ็กเกจ
- เลือกแพ็กเกจ Blaze ทำตามวิธีการบนหน้าจอเพื่อลิงก์บัญชีสำหรับการเรียกเก็บเงินใน Cloud กับโปรเจ็กต์
หากคุณต้องสร้างบัญชีสำหรับการเรียกเก็บเงินใน Cloud เป็นส่วนหนึ่งของการอัปเกรดนี้ คุณอาจต้องกลับไปที่ขั้นตอนการอัปเกรดใน Firebase Console เพื่อทำการอัปเกรดให้เสร็จสมบูรณ์
เปิดใช้และตั้งค่าผลิตภัณฑ์ Firebase ในคอนโซล
แอปที่คุณสร้างใช้ผลิตภัณฑ์ Firebase หลายอย่างที่พร้อมใช้งานสำหรับแอป Apple ดังนี้
- การตรวจสอบสิทธิ์ Firebase เพื่อให้ผู้ใช้ลงชื่อเข้าใช้แอปของคุณได้อย่างง่ายดาย
- Cloud Firestore เพื่อบันทึกข้อมูลที่มีโครงสร้างไว้ในระบบคลาวด์และรับการแจ้งเตือนทันทีเมื่อข้อมูลมีการเปลี่ยนแปลง
- กฎการรักษาความปลอดภัยของ Firebase เพื่อรักษาความปลอดภัยให้ฐานข้อมูล
ผลิตภัณฑ์บางอย่างเหล่านี้ต้องมีการกำหนดค่าพิเศษหรือต้องเปิดใช้โดยใช้คอนโซล Firebase
เปิดใช้การตรวจสอบสิทธิ์แบบไม่ระบุชื่อสำหรับการตรวจสอบสิทธิ์ Firebase
แอปพลิเคชันนี้ใช้การตรวจสอบสิทธิ์ที่ไม่ระบุชื่อเพื่อให้ผู้ใช้เริ่มใช้แอปได้โดยไม่ต้องสร้างบัญชีก่อน ซึ่งส่งผลให้กระบวนการเริ่มต้นใช้งานราบรื่น ดูข้อมูลเพิ่มเติมเกี่ยวกับการตรวจสอบสิทธิ์แบบไม่ระบุชื่อ (และวิธีอัปเกรดเป็นบัญชีที่มีชื่อ) ได้ที่แนวทางปฏิบัติแนะนำสำหรับการตรวจสอบสิทธิ์แบบไม่ระบุชื่อ
- ในแผงด้านซ้ายของคอนโซล Firebase ให้คลิกสร้าง > การตรวจสอบสิทธิ์ จากนั้นคลิกเริ่มต้นใช้งาน
- ตอนนี้คุณอยู่ในแดชบอร์ดการตรวจสอบสิทธิ์ ซึ่งคุณสามารถดูผู้ใช้ที่ลงชื่อสมัครใช้ กำหนดค่าผู้ให้บริการลงชื่อเข้าใช้ และจัดการการตั้งค่าได้
- เลือกแท็บวิธีการลงชื่อเข้าใช้ (หรือคลิกที่นี่เพื่อไปที่แท็บโดยตรง)
- คลิกไม่ระบุตัวตนจากตัวเลือกผู้ให้บริการ สลับปุ่มเป็นเปิดใช้ แล้วคลิกบันทึก
ตั้งค่า Cloud Firestore
แอปพลิเคชัน Swift นี้ใช้ Cloud Firestore เพื่อบันทึกโน้ต
วิธีตั้งค่า Cloud Firestore ในโปรเจ็กต์ Firebase มีดังนี้
- ในแผงด้านซ้ายของคอนโซล Firebase ให้ขยายสร้าง แล้วเลือกฐานข้อมูล Firestore
- คลิกสร้างฐานข้อมูล
- ตั้งค่ารหัสฐานข้อมูลเป็น
(default)
ไว้ดังเดิม - เลือกตำแหน่งสำหรับฐานข้อมูล แล้วคลิกถัดไป
สำหรับแอปจริง คุณควรเลือกตำแหน่งที่อยู่ใกล้กับผู้ใช้ - คลิกเริ่มในโหมดทดสอบ อ่านข้อจำกัดความรับผิดเกี่ยวกับกฎความปลอดภัย
ในภายหลังใน Codelab นี้ คุณจะเพิ่มกฎความปลอดภัยเพื่อรักษาความปลอดภัยของข้อมูล อย่าเผยแพร่หรือเปิดเผยแอปต่อสาธารณะโดยไม่ได้เพิ่มกฎความปลอดภัยสำหรับฐานข้อมูล - คลิกสร้าง
ตั้งค่า Cloud Storage for Firebase
เว็บแอปใช้ Cloud Storage for Firebase เพื่อจัดเก็บ อัปโหลด และแชร์รูปภาพ
วิธีตั้งค่า Cloud Storage for Firebase ในโปรเจ็กต์ Firebase มีดังนี้
- ในแผงด้านซ้ายของคอนโซล Firebase ให้ขยายสร้าง แล้วเลือก Storage
- คลิกเริ่มต้นใช้งาน
- เลือกตำแหน่งสำหรับที่เก็บข้อมูลเริ่มต้น
ที่เก็บข้อมูลในUS-WEST1
,US-CENTRAL1
และUS-EAST1
จะใช้ประโยชน์จากระดับ"ใช้งานฟรีเสมอ" สำหรับ Google Cloud Storage ได้ ที่เก็บข้อมูลในตำแหน่งอื่นๆ ทั้งหมดจะเป็นไปตามราคาและการใช้งาน Google Cloud Storage - คลิกเริ่มในโหมดทดสอบ อ่านข้อจำกัดความรับผิดเกี่ยวกับกฎความปลอดภัย
ในภายหลังใน Codelab นี้ คุณจะเพิ่มกฎความปลอดภัยเพื่อรักษาความปลอดภัยของข้อมูล อย่าเผยแพร่หรือแสดงแอปต่อสาธารณะโดยไม่ได้เพิ่มกฎความปลอดภัยสำหรับที่เก็บข้อมูล - คลิกสร้าง
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)
- คุณป้อนชื่อเล่นแอปได้หากต้องการ (Notes สำหรับ 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
ในส่วนนี้ของ Codelab คุณจะติดตั้งส่วนขยายการค้นหาเวกเตอร์ด้วย 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
เอกสาร โดยควรแสดงว่าส่วนขยายประมวลผลการฝังสำหรับเอกสารบันทึกทั้งหมดที่คุณสร้างในขั้นตอนก่อนหน้าใน Codelab นี้เสร็จแล้ว - หากต้องการยืนยัน ให้เปิดเอกสารบันทึกย่อใดก็ได้ แล้วคุณจะเห็นช่องเพิ่มเติมชื่อ
embedding
ประเภทvector<768>
รวมถึงช่องstatus
สร้างเอกสารตัวอย่าง
คุณสร้างเอกสารใหม่ในคอนโซล Firebase เพื่อดูการทำงานของส่วนขยายได้
- ในเครื่องมือสำรวจข้อมูล Firestore ให้ไปที่คอลเล็กชัน
notes
แล้วคลิก + เพิ่มเอกสาร ในคอลัมน์กลาง - คลิกรหัสอัตโนมัติเพื่อสร้างรหัสเอกสารที่ไม่ซ้ำกันใหม่
- เพิ่มฟิลด์ชื่อ
text
ประเภทสตริง แล้ววางข้อความลงในฟิลด์ค่า โปรดทราบว่าข้อความนี้ต้องไม่ใช่ข้อความลอเร็มอิปซัมหรือข้อความแบบสุ่มอื่นๆ เช่น เลือกบทความข่าว - คลิกบันทึก
- สังเกตว่าส่วนขยายเพิ่มช่องสถานะเพื่อระบุว่ากำลังประมวลผลข้อมูล
- หลังจากนั้นไม่นาน คุณจะเห็นฟิลด์ใหม่
embedding
ที่มีค่าเป็นvector<768>
ทำการค้นหา
ส่วนขยายการค้นหาเวกเตอร์ด้วย Firestore มีฟีเจอร์เล็กๆ ที่ยอดเยี่ยมซึ่งช่วยให้คุณค้นหาดัชนีเอกสารได้โดยไม่ต้องเชื่อมต่อแอป
- ในส่วน Firestore ของคอนโซล Firebase ให้ไปที่
_firestore-vector-search/index
เอกสาร - คลิก + เริ่มคอลเล็กชัน
- สร้างคอลเล็กชันย่อยใหม่ชื่อ
queries
- สร้างเอกสารใหม่และตั้งค่าฟิลด์
query
เป็นข้อความที่อยู่ในเอกสารใดเอกสารหนึ่ง วิธีนี้เหมาะที่สุดสำหรับการค้นหาเชิงความหมาย เช่น "ฉันจะแมปเอกสาร Firestore กับ Swift ได้อย่างไร" (หากโน้ตที่คุณเพิ่มมีข้อความที่พูดถึงหัวข้อนี้อย่างน้อย 1 รายการ) - คุณอาจเห็นข้อผิดพลาดในสถานะ
- เนื่องจากไม่มีดัชนี หากต้องการตั้งค่าการกำหนดค่าดัชนีที่ขาดหายไป ให้ไปที่คอนโซล Google Cloud สำหรับโปรเจ็กต์โดยทำตามลิงก์นี้ แล้วเลือกโปรเจ็กต์จากรายการ
- ใน Cloud Log Explorer คุณควรเห็นข้อความแสดงข้อผิดพลาดที่ระบุว่า "FAILED_PRECONDITION: Missing vector index configuration. โปรดสร้างดัชนีที่จำเป็นด้วยคำสั่ง 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. ใช้การค้นหาเชิงความหมาย
ในที่สุดก็ถึงเวลาเชื่อมต่อแอปบนอุปกรณ์เคลื่อนที่กับส่วนขยายการค้นหาเวกเตอร์ด้วย Firestore และใช้ฟีเจอร์การค้นหาเชิงความหมายที่จะช่วยให้ผู้ใช้ค้นหาโน้ตได้โดยใช้คำค้นหาที่เป็นภาษาธรรมชาติ
เชื่อมต่อฟังก์ชันที่เรียกใช้ได้เพื่อทำการค้นหา
ส่วนขยายการค้นหาเวกเตอร์ด้วย Firestore มี Cloud Functions ที่คุณเรียกใช้จากแอปบนอุปกรณ์เคลื่อนที่เพื่อค้นหาดัชนีที่สร้างไว้ก่อนหน้านี้ในโค้ดแล็บนี้ได้ ในขั้นตอนนี้ คุณจะสร้างการเชื่อมต่อระหว่างแอปบนอุปกรณ์เคลื่อนที่กับฟังก์ชันที่เรียกใช้ได้นี้ Swift SDK ของ Firebase มี API ที่ทำให้การเรียกใช้ฟังก์ชันระยะไกลเป็นไปอย่างราบรื่น
- กลับไปที่ Xcode และตรวจสอบว่าคุณอยู่ในโปรเจ็กต์ที่โคลนในขั้นตอนก่อนหน้าของ Codelab นี้
- เปิดไฟล์
NotesRepository.swift
- ค้นหาบรรทัดที่มี
private lazy var vectorSearchQueryCallable: Callable
= functions.httpsCallable("")
หากต้องการเรียกใช้ Cloud Function ที่เรียกใช้ได้ คุณต้องระบุชื่อของฟังก์ชันที่ต้องการเรียกใช้
- ไปที่คอนโซล 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 [] } }
เชื่อมต่อ UI
หากต้องการอนุญาตให้ผู้ใช้ค้นหาโน้ต คุณจะต้องติดตั้งแถบค้นหาในหน้าจอรายการโน้ต เมื่อผู้ใช้พิมพ์ข้อความค้นหา คุณจะต้องเรียกใช้เมธอด 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 Simulator
- คุณควรเห็นโน้ตเดียวกันกับที่เพิ่มไว้ในแอปก่อนหน้านี้ใน 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 นี้สำเร็จ
ในโค้ดแล็บนี้ คุณได้เรียนรู้วิธีทำสิ่งต่อไปนี้
- ตั้งค่าฐานข้อมูล Cloud Firestore โดยเปิดใช้การค้นหาเชิงความหมาย
- สร้างแอป SwiftUI อย่างง่ายเพื่อโต้ตอบกับฐานข้อมูล
- ใช้แถบค้นหาโดยใช้ตัวแก้ไขมุมมองที่ค้นหาได้ของ SwiftUI และตัวแก้ไขงาน
- เรียกใช้ Cloud Functions เพื่อทำการค้นหาเชิงความหมายในฐานข้อมูลโดยใช้อินเทอร์เฟซที่เรียกใช้ได้ของ Firestore SDK
ความรู้ที่คุณได้รับจาก Codelab นี้จะช่วยให้คุณสร้างแอปพลิเคชันที่มีประสิทธิภาพซึ่งใช้ประโยชน์จากความสามารถในการค้นหาเชิงความหมายของ Cloud Firestore เพื่อมอบประสบการณ์การค้นหาที่ใช้งานง่ายและมีประสิทธิภาพมากขึ้นแก่ผู้ใช้ได้
ดูข้อมูลเพิ่มเติมเกี่ยวกับฟิลด์เวกเตอร์ใหม่ของ Firestore และวิธีคำนวณการฝังเวกเตอร์ได้ที่เอกสารประกอบ