เพิ่มการค้นหาเวกเตอร์ของ Firestore ในแอปบนอุปกรณ์เคลื่อนที่ด้วย Firebase Extensions

1. ภาพรวม

ใน Codelab นี้ คุณจะได้เรียนรู้วิธีเพิ่มฟีเจอร์การค้นหาที่มีประสิทธิภาพลงในแอปโดยใช้การค้นหาความคล้ายคลึงกันของเวกเตอร์ของ Firestore คุณจะใช้ฟีเจอร์การค้นหาเชิงความหมายสําหรับแอปจดบันทึกที่เขียนด้วย Swift และ SwiftUI

คอนโซล Cloud Firestore ที่แสดงเอกสารบางรายการ ซึ่งจะปรากฏในแอป iOS ทางด้านขวามือด้วย

สิ่งที่คุณจะได้เรียนรู้

สิ่งที่ต้องมี

  • Xcode 15.3
  • โค้ดตัวอย่างของ Codelab คุณจะดาวน์โหลดไฟล์นี้ในขั้นตอนถัดไปของโค้ดแล็บ

2. สร้างและตั้งค่าโปรเจ็กต์ Firebase

ในการใช้ส่วนขยาย Firebase Vector Search คุณต้องมีโปรเจ็กต์ Firebase ในส่วนนี้ของโค้ดแล็บ คุณจะได้สร้างโปรเจ็กต์ Firebase ใหม่ และเปิดใช้งานบริการที่จําเป็น เช่น Cloud Firestore และ Firebase Authentication

สร้างโปรเจ็กต์ Firebase

  1. ลงชื่อเข้าใช้ Firebase
  2. ในคอนโซล Firebase ให้คลิกเพิ่มโปรเจ็กต์ แล้วตั้งชื่อโปรเจ็กต์เป็น Firestore Vector Search Labสร้างโปรเจ็กต์ ขั้นตอนที่ 1 จาก 3: เลือกชื่อโปรเจ็กต์
  3. คลิกตัวเลือกการสร้างโปรเจ็กต์ ยอมรับข้อกำหนดของ Firebase หากได้รับข้อความแจ้ง
  4. ในหน้าจอ Google Analytics ให้ยกเลิกการเลือกช่องเปิดใช้ Google Analytics สําหรับโปรเจ็กต์นี้ เนื่องจากคุณจะไม่ได้ใช้ Analytics สําหรับแอปนี้
  5. สุดท้าย ให้คลิกสร้างโปรเจ็กต์

ดูข้อมูลเพิ่มเติมเกี่ยวกับโปรเจ็กต์ Firebase ได้ที่ทําความเข้าใจโปรเจ็กต์ Firebase

อัปเกรดแพ็กเกจราคา Firebase

หากต้องการใช้ Firebase Extensions และบริการระบบคลาวด์ที่เกี่ยวข้อง โปรเจ็กต์ Firebase ของคุณจะต้องอยู่ในแพ็กเกจราคาแบบชําระเงินตามการใช้งาน (Blaze) ซึ่งหมายความว่าโปรเจ็กต์จะลิงก์กับบัญชีการเรียกเก็บเงินในระบบคลาวด์

หากต้องการอัปเกรดโปรเจ็กต์เป็นแพ็กเกจ Blaze ให้ทำตามขั้นตอนต่อไปนี้

  1. ในคอนโซล Firebase ให้เลือกอัปเกรดแพ็กเกจ
  2. เลือกแพ็กเกจ Blaze ทำตามวิธีการบนหน้าจอเพื่อลิงก์บัญชีสำหรับการเรียกเก็บเงินใน Cloud กับโปรเจ็กต์
    หากจำเป็นต้องสร้างบัญชีสำหรับการเรียกเก็บเงินใน Cloud เป็นส่วนหนึ่งของการอัปเกรดนี้ คุณอาจต้องกลับไปที่ขั้นตอนการอัปเกรดในคอนโซล Firebase เพื่อดำเนินการอัปเกรดให้เสร็จสมบูรณ์

เปิดใช้และตั้งค่าผลิตภัณฑ์ Firebase ในคอนโซล

แอปที่คุณกําลังสร้างใช้ผลิตภัณฑ์ Firebase หลายรายการที่พร้อมให้บริการสําหรับแอป Apple ดังนี้

  • การตรวจสอบสิทธิ์ของ Firebase เพื่อให้ผู้ใช้ลงชื่อเข้าใช้แอปได้ง่ายๆ
  • Cloud Firestore เพื่อบันทึก Structured Data ในระบบคลาวด์และรับการแจ้งเตือนทันทีเมื่อมีการเปลี่ยนแปลงข้อมูล
  • กฎการรักษาความปลอดภัยของ Firebase เพื่อรักษาความปลอดภัยให้ฐานข้อมูล

ผลิตภัณฑ์เหล่านี้บางรายการต้องมีการกำหนดค่าพิเศษหรือต้องเปิดใช้โดยใช้คอนโซล Firebase

เปิดใช้การตรวจสอบสิทธิ์แบบไม่ระบุชื่อสําหรับการตรวจสอบสิทธิ์ Firebase

แอปพลิเคชันนี้ใช้การตรวจสอบสิทธิ์แบบไม่ระบุชื่อเพื่อให้ผู้ใช้เริ่มใช้แอปได้โดยไม่ต้องสร้างบัญชีก่อน ซึ่งทำให้กระบวนการเริ่มต้นใช้งานเป็นไปอย่างราบรื่น ดูข้อมูลเพิ่มเติมเกี่ยวกับการตรวจสอบสิทธิ์แบบไม่ระบุชื่อ (และวิธีอัปเกรดเป็นบัญชีที่มีชื่อ) ได้ที่แนวทางปฏิบัติแนะนำสำหรับการตรวจสอบสิทธิ์แบบไม่ระบุชื่อ

  1. ในแผงด้านซ้ายของคอนโซล Firebase ให้คลิก Build > Authentication จากนั้นคลิกเริ่มต้นใช้งานการเปิดใช้การตรวจสอบสิทธิ์ Firebase
  2. ตอนนี้คุณอยู่ในแดชบอร์ดการตรวจสอบสิทธิ์ ซึ่งคุณสามารถดูผู้ใช้ที่ลงชื่อสมัครใช้ กำหนดค่าผู้ให้บริการลงชื่อเข้าใช้ และจัดการการตั้งค่าได้
  3. เลือกแท็บวิธีการลงชื่อเข้าใช้ (หรือคลิกที่นี่เพื่อไปที่แท็บโดยตรง)
  4. คลิกไม่ระบุตัวตนจากตัวเลือกผู้ให้บริการ สลับสวิตช์เป็นเปิดใช้ แล้วคลิกบันทึก

ตั้งค่า Cloud Firestore

แอปพลิเคชัน Swift นี้ใช้ Cloud Firestore เพื่อบันทึกโน้ต

วิธีตั้งค่า Cloud Firestore ในโปรเจ็กต์ Firebase มีดังนี้

  1. ในแผงด้านซ้ายของคอนโซล Firebase ให้ขยายสร้าง แล้วเลือกฐานข้อมูล Firestore
  2. คลิกสร้างฐานข้อมูล
  3. ตั้งค่ารหัสฐานข้อมูลเป็น (default)
  4. เลือกตำแหน่งของฐานข้อมูล แล้วคลิกถัดไป
    สำหรับแอปจริง คุณจะต้องเลือกตำแหน่งที่ใกล้กับผู้ใช้
  5. คลิกเริ่มในโหมดทดสอบ อ่านข้อจำกัดความรับผิดเกี่ยวกับกฎการรักษาความปลอดภัย
    ในภายหลังในโค้ดแล็บนี้ คุณจะเพิ่มกฎการรักษาความปลอดภัยเพื่อรักษาความปลอดภัยให้กับข้อมูล อย่าเผยแพร่หรือแสดงแอปต่อสาธารณะโดยไม่เพิ่มกฎความปลอดภัยสําหรับฐานข้อมูล
  6. คลิกสร้าง

ตั้งค่า Cloud Storage สำหรับ Firebase

เว็บแอปใช้ Cloud Storage for Firebase เพื่อจัดเก็บ อัปโหลด และแชร์รูปภาพ

วิธีตั้งค่า Cloud Storage for Firebase ในโปรเจ็กต์ Firebase มีดังนี้

  1. ในแผงด้านซ้ายของคอนโซล Firebase ให้ขยายบิลด์ แล้วเลือกพื้นที่เก็บข้อมูล
  2. คลิกเริ่มต้นใช้งาน
  3. เลือกตำแหน่งสำหรับที่เก็บข้อมูลเริ่มต้น
    ที่เก็บข้อมูลใน US-WEST1, US-CENTRAL1 และ US-EAST1 สามารถใช้แพ็กเกจ "ฟรีตลอด" สำหรับ Google Cloud Storage ที่เก็บข้อมูลในตำแหน่งอื่นๆ ทั้งหมดจะเป็นไปตามราคาและการใช้งาน Google Cloud Storage
  4. คลิกเริ่มในโหมดทดสอบ อ่านข้อจำกัดความรับผิดเกี่ยวกับกฎการรักษาความปลอดภัย
    ในภายหลังในโค้ดแล็บนี้ คุณจะต้องเพิ่มกฎการรักษาความปลอดภัยเพื่อรักษาความปลอดภัยให้ข้อมูล อย่าเผยแพร่หรือแสดงแอปต่อสาธารณะโดยไม่เพิ่มกฎความปลอดภัยสำหรับที่เก็บข้อมูล
  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. คุณสามารถป้อนชื่อเล่นแอป (Notes for iOS) ได้หากต้องการ
  5. คลิก "ลงทะเบียนแอป" เพื่อไปยังขั้นตอนถัดไป
  6. ดาวน์โหลดไฟล์ GoogleServices-Info.plist
  7. ลาก GoogleServices-Info.plist ลงในโฟลเดอร์ Notes ของโปรเจ็กต์ Xcode วิธีที่ดีในการทำเช่นนี้คือการวางไว้ใต้ไฟล์ Assets.xcassetsการลากไฟล์ plist ไปยัง Xcode
  8. เลือกคัดลอกรายการหากจําเป็น ตรวจสอบว่าได้เลือกเป้าหมายหมายเหตุในเพิ่มลงในเป้าหมาย แล้วคลิกเสร็จสิ้นเลือก "คัดลอกหากจำเป็น" ในกล่องโต้ตอบตัวเลือกสำหรับเพิ่มไฟล์
  9. ในคอนโซล Firebase คุณจะคลิกผ่านขั้นตอนการตั้งค่าที่เหลือได้ เช่น ตัวอย่างที่คุณดาวน์โหลดในตอนต้นของส่วนนี้มี Firebase Apple SDK ติดตั้งอยู่แล้ว รวมถึงการตั้งค่าการเริ่มต้น คุณดำเนินการให้เสร็จสิ้นได้โดยคลิกดำเนินการต่อไปยังคอนโซล

เรียกใช้แอป

ตอนนี้ถึงเวลาลองใช้แอปแล้ว

  1. กลับไปที่ Xcode แล้วเรียกใช้แอปในโปรแกรมจำลอง iOS ในเมนูแบบเลื่อนลงปลายทางการเรียกใช้ ให้เลือกโปรแกรมจำลอง iOS รายการใดรายการหนึ่งก่อนการเลือกเครื่องจำลอง iOS ในเมนูแบบเลื่อนลง "ปลายทางการเรียกใช้"
  2. จากนั้นคลิกปุ่มเรียกใช้ หรือกด ⌘ + R
  3. เมื่อแอปเปิดใช้งานบนเครื่องจำลองเรียบร้อยแล้ว ให้เพิ่มหมายเหตุ 2-3 รายการ
  4. ในคอนโซล Firebase ให้ไปที่เครื่องมือเรียกดูข้อมูล Firestore เพื่อให้คุณเห็นเอกสารใหม่ที่กำลังสร้างขึ้นเมื่อเพิ่มโน้ตใหม่ในแอปคอนโซล Cloud Firestore ที่แสดงเอกสารบางรายการควบคู่ไปกับโปรแกรมจำลอง iOS ที่แสดงเอกสารเดียวกัน

4. ติดตั้งส่วนขยายการค้นหาเวกเตอร์ด้วย Firestore

ในส่วนนี้ของโค้ดแล็บ คุณจะติดตั้งส่วนขยายการค้นหาเวกเตอร์ด้วย Firestore และกำหนดค่าตามข้อกำหนดของแอปจดบันทึกที่คุณกำลังพัฒนา

เริ่มติดตั้งส่วนขยาย

  1. ขณะยังอยู่ในส่วน Firestore ให้คลิกแท็บส่วนขยายการเลือกแท็บ Firebase Extensions ในคอนโซล Firestore
  2. คลิกสำรวจฮับส่วนขยายแท็บ Firebase Extensions ในคอนโซล Firestore
  3. พิมพ์ "เวกเตอร์"
  4. คลิก "การค้นหาเวกเตอร์ด้วยส่วนขยาย Firestore"หน้า Landing Page ของ Firebase Extensions Hub ซึ่งจะนำคุณไปยังหน้ารายละเอียดของส่วนขยาย ซึ่งคุณสามารถอ่านข้อมูลเพิ่มเติมเกี่ยวกับส่วนขยาย วิธีการทำงานของส่วนขยาย บริการ Firebase ที่จำเป็น และวิธีกำหนดค่าส่วนขยาย
  5. คลิกติดตั้งในคอนโซล Firebaseปุ่มติดตั้งสำหรับส่วนขยายการค้นหาเวกเตอร์ด้วย Firestore
  6. คุณจะเห็นรายการโปรเจ็กต์ทั้งหมด
  7. เลือกโปรเจ็กต์ที่คุณสร้างในขั้นตอนแรกของ Codelab นี้หน้าจอตัวเลือกโปรเจ็กต์ Firebase

กําหนดค่าส่วนขยาย

  1. ตรวจสอบการเปิดใช้ API และสร้างทรัพยากรการตรวจสอบ API ที่เปิดใช้
  2. เปิดใช้บริการที่จำเป็นการเปิดใช้บริการที่จําเป็น
  3. เมื่อเปิดใช้บริการทั้งหมดแล้ว ให้คลิกถัดไปคลิก "ถัดไป" หลังจากเปิดใช้บริการทั้งหมด
  4. ตรวจสอบสิทธิ์เข้าถึงที่มอบให้ส่วนขยายนี้
  5. กําหนดค่าส่วนขยาย
    • เลือก Vertex AI เป็น LLM
    • เส้นทางคอลเล็กชัน: notes
    • ขีดจำกัดการค้นหาเริ่มต้น: 3
    • ชื่อช่องสำหรับป้อนข้อมูล: text
    • ชื่อช่องเอาต์พุต: embedding
    • ชื่อช่องสถานะ:* *status*
    • ฝังเอกสารที่มีอยู่: ใช่
    • อัปเดตเอกสารที่มีอยู่: ใช่
    • ตำแหน่ง Cloud Function: us-central1
  6. คลิกติดตั้งส่วนขยายเพื่อดำเนินการติดตั้งให้เสร็จสิ้น

การดำเนินการนี้อาจใช้เวลาสักครู่ ขณะรอให้การติดตั้งเสร็จสมบูรณ์ คุณสามารถข้ามไปยังส่วนถัดไปของบทแนะนําและอ่านข้อมูลเบื้องต้นเกี่ยวกับเวกเตอร์เชิงลึกได้

5. ข้อมูลเบื้องต้น

ขณะรอให้การติดตั้งเสร็จสมบูรณ์ ต่อไปนี้เป็นข้อมูลเบื้องต้นเกี่ยวกับวิธีการทำงานของการค้นหาด้วยเวกเตอร์ด้วยส่วนขยาย Firestore

ฐานข้อมูลเวกเตอร์ การฝัง และฐานข้อมูลเวกเตอร์คืออะไร

  • เวกเตอร์เป็นวัตถุทางคณิตศาสตร์ที่แสดงขนาดและทิศทางของจำนวน สามารถใช้เพื่อแสดงข้อมูลในลักษณะที่ทําให้เปรียบเทียบและค้นหาได้ง่ายขึ้น
  • การฝังคือเวกเตอร์ที่แสดงถึงความหมายของคำหรือวลี โดยสร้างขึ้นจากการฝึกโครงข่ายระบบประสาทเทียมด้วยชุดข้อความขนาดใหญ่และเรียนรู้ความสัมพันธ์ระหว่างคำ
  • ฐานข้อมูลเวกเตอร์เป็นฐานข้อมูลที่ได้รับการเพิ่มประสิทธิภาพสำหรับการจัดเก็บและค้นหาข้อมูลเวกเตอร์ ทำให้ค้นหาเพื่อนบ้านที่อยู่ใกล้ที่สุดได้อย่างมีประสิทธิภาพ ซึ่งเป็นกระบวนการหาเวกเตอร์ที่คล้ายกับเวกเตอร์ของคำค้นหามากที่สุด

การทำงานการค้นหาเวกเตอร์

การค้นหาเวกเตอร์ทำงานโดยการเปรียบเทียบเวกเตอร์การค้นหากับเวกเตอร์ทั้งหมดในฐานข้อมูล เวกเตอร์ที่คล้ายกับเวกเตอร์การค้นหามากที่สุดจะแสดงผลเป็นผลการค้นหา

ความคล้ายคลึงกันระหว่างเวกเตอร์ 2 รายการสามารถวัดได้โดยใช้เมตริกระยะทางที่หลากหลาย เมตริกระยะทางที่ใช้กันมากที่สุดคือความคล้ายคลึงของโคไซน์ ซึ่งจะวัดมุมระหว่างเวกเตอร์ 2 รายการ

6. ลองใช้การค้นหาเวกเตอร์ด้วยส่วนขยาย Firestore

ก่อนใช้การค้นหาเวกเตอร์ด้วยส่วนขยาย Firestore ในแอป iOS ที่คุณดาวน์โหลดไว้ก่อนหน้านี้ในโค้ดแล็บนี้ คุณสามารถลองใช้ส่วนขยายในคอนโซล Firebase ได้

อ่านเอกสารประกอบ

Firebase Extensions มีเอกสารประกอบเกี่ยวกับวิธีการทํางาน

  1. เมื่อติดตั้งส่วนขยายเสร็จแล้ว ให้คลิกปุ่มเริ่มต้นใช้งาน หน้าภาพรวมของ Firebase Extensions ในคอนโซล Firebase
  2. โปรดดูแท็บ "วิธีการทำงานของส่วนขยายนี้" ซึ่งจะอธิบายข้อมูลต่อไปนี้
    • วิธีประมวลผลการฝังสำหรับเอกสารโดยการเพิ่มไปยังคอลเล็กชัน notes
    • วิธีค้นหาดัชนีโดยการเรียกใช้ext-firestore-vector-search-queryCallableฟังก์ชันที่เรียกใช้ได้
    • หรือวิธีค้นหาดัชนีโดยเพิ่มเอกสารการค้นหาลงในคอลเล็กชัน _firestore-vector-search/index/queries
    • นอกจากนี้ ยังอธิบายวิธีตั้งค่าฟังก์ชันการฝังที่กำหนดเอง ซึ่งมีประโยชน์ในกรณีที่ LLM ทั้งหมดที่ส่วนขยายรองรับไม่ตรงกับข้อกำหนดของคุณ และคุณต้องการใช้ LLM อื่นเพื่อคํานวณการฝัง เอกสารสำหรับ Vector Search ที่มีส่วนขยาย Firestore
  3. คลิกลิงก์แดชบอร์ด Cloud Firestore เพื่อไปยังอินสแตนซ์ Firestore
  4. ไปที่เอกสาร _firestore-vector-search/index ซึ่งควรแสดงว่าส่วนขยายได้ประมวลผลการฝังสําหรับเอกสารโน้ตทั้งหมดที่คุณสร้างในขั้นตอนก่อนหน้าในโค้ดแล็บนี้แล้วการกำหนดค่าดัชนีภายในคอนโซล Firestore
  5. หากต้องการยืนยัน ให้เปิดเอกสารโน้ตรายการใดรายการหนึ่ง แล้วคุณจะเห็นช่องเพิ่มเติมชื่อ embedding ประเภท vector<768> รวมถึงช่อง statusช่องการฝังเวกเตอร์ภายในคอนโซล Firestore

สร้างเอกสารตัวอย่าง

คุณสร้างเอกสารใหม่ในคอนโซล Firebase เพื่อดูการทำงานของส่วนขยายได้

  1. ยังคงอยู่ในเครื่องมือเรียกดูข้อมูล Firestore ให้ไปที่คอลเล็กชัน notes แล้วคลิก + เพิ่มเอกสารในคอลัมน์กลางการเพิ่มเอกสารใหม่
  2. คลิกรหัสอัตโนมัติเพื่อสร้างรหัสเอกสารใหม่ที่ไม่ซ้ำกัน
  3. เพิ่มช่องชื่อ text ประเภทสตริง แล้ววางข้อความบางส่วนลงในช่อง value ข้อความนี้ต้องไม่ใช่ข้อความ Lorem ipsum หรือข้อความสุ่มอื่นๆ เลือกบทความข่าว เป็นต้นการเพิ่มช่องข้อความ
  4. คลิกบันทึก
    • โปรดสังเกตวิธีที่ส่วนขยายเพิ่มช่องสถานะเพื่อระบุว่ากําลังประมวลผลข้อมูล
    • หลังจากผ่านไปสักครู่ คุณควรเห็นช่อง embedding ใหม่ที่มีค่าเป็น vector<768>
    อัปเดตสถานะการฝังเวกเตอร์สำหรับเอกสารใหม่

ทำการค้นหา

การค้นหาเวกเตอร์ด้วยส่วนขยาย Firestore มีฟีเจอร์เล็กๆ น้อยๆ ที่มีประโยชน์ซึ่งช่วยให้คุณค้นหาดัชนีเอกสารได้โดยไม่ต้องเชื่อมต่อแอป

  1. ในส่วน Firestore ของคอนโซล Firebase ให้ไปที่เอกสาร _firestore-vector-search/index
  2. คลิก + เริ่มคอลเล็กชันการเพิ่มคอลเล็กชันย่อยใหม่
  3. สร้างคอลเล็กชันย่อยใหม่ชื่อ queries
  4. สร้างเอกสารใหม่และตั้งค่าช่อง query เป็นข้อความที่ปรากฏในเอกสาร วิธีนี้เหมาะกับการค้นหาเชิงความหมาย เช่น "ฉันจะแมปเอกสาร Firestore กับ Swift ได้อย่างไร" (โดยมีเงื่อนไขว่าโน้ตที่คุณเพิ่มอย่างน้อย 1 รายการมีข้อความที่พูดถึงหัวข้อนี้)การเพิ่มช่องการค้นหา
  5. คุณอาจเห็นข้อผิดพลาดในสถานะเกิดข้อผิดพลาด
  6. เนื่องจากไม่มีดัชนี หากต้องการตั้งค่าการกําหนดค่าดัชนีที่ขาดหายไป ให้ไปที่คอนโซล Google Cloud สําหรับโปรเจ็กต์โดยไปที่ลิงก์นี้ แล้วเลือกโปรเจ็กต์จากรายการการเลือกโปรเจ็กต์ที่ถูกต้อง
  7. ใน Logs Explorer ของ Cloud คุณควรเห็นข้อความแสดงข้อผิดพลาด "FAILED_PRECONDITION: ไม่มีการกำหนดค่าดัชนีเวกเตอร์ โปรดสร้างดัชนีที่จำเป็นด้วยคำสั่ง gcloud ต่อไปนี้: ..."ข้อความแสดงข้อผิดพลาดในเครื่องมือสํารวจบันทึก
  8. ข้อความแสดงข้อผิดพลาดยังมีคำสั่ง gcloud ที่คุณต้องเรียกใช้เพื่อกำหนดค่าดัชนีที่หายไปด้วย
  9. เรียกใช้คำสั่งต่อไปนี้จากบรรทัดคำสั่ง หากไม่ได้ติดตั้ง gcloud CLI ในเครื่อง ให้ทำตามวิธีการที่นี่เพื่อติดตั้ง
    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
    
    การสร้างดัชนีใช้เวลา 2-3 นาที คุณดูความคืบหน้าได้ในแท็บดัชนีในส่วน Firestore ของคอนโซล Firebaseสถานะของดัชนีใหม่
  10. เมื่อตั้งค่าดัชนีแล้ว คุณสามารถสร้างเอกสารการค้นหาใหม่ได้
  11. ตอนนี้คุณควรเห็นรายการรหัสเอกสารที่ตรงกันในช่องผลลัพธ์ผลการค้นหาเชิงความหมาย
  12. คัดลอกรหัสใดรหัสหนึ่ง แล้วกลับไปที่คอลเล็กชัน notes
  13. ใช้ ⌘+F เพื่อค้นหารหัสเอกสารที่คุณคัดลอก เอกสารนี้เป็นเอกสารที่ตรงกับคำค้นหาของคุณมากที่สุดการค้นหารหัสเอกสารในรายการเอกสาร

7. ใช้การค้นหาเชิงความหมาย

ตอนนี้ถึงเวลาเชื่อมต่อแอปบนอุปกรณ์เคลื่อนที่กับ Vector Search ด้วยส่วนขยาย Firestore และใช้งานฟีเจอร์การค้นหาเชิงความหมายที่จะช่วยให้ผู้ใช้ค้นหาโน้ตโดยใช้การค้นหาด้วยภาษาที่เป็นธรรมชาติ

เชื่อมต่อฟังก์ชันที่เรียกใช้ได้สําหรับการค้นหา

การค้นหา Vector Search ด้วยส่วนขยาย Firestore มี Cloud Function ที่คุณเรียกใช้จากแอปบนอุปกรณ์เคลื่อนที่เพื่อค้นหาดัชนีที่สร้างไว้ก่อนหน้านี้ใน Codelab ได้ ในขั้นตอนนี้ คุณจะต้องสร้างการเชื่อมต่อระหว่างแอปบนอุปกรณ์เคลื่อนที่กับฟังก์ชันที่เรียกใช้ได้นี้ Swift SDK ของ Firebase มี API ที่ทำให้การเรียกใช้ฟังก์ชันระยะไกลเป็นไปอย่างราบรื่น

  1. กลับไปที่ Xcode และตรวจสอบว่าคุณอยู่ในโปรเจ็กต์ที่คุณโคลนในขั้นตอนก่อนหน้าในโค้ดแล็บนี้
  2. เปิดไฟล์ NotesRepository.swift
  3. ค้นหาบรรทัดที่มี private lazy var vectorSearchQueryCallable: Callable = functions.httpsCallable("")

หากต้องการเรียกใช้ Cloud Function ที่เรียกใช้ได้ คุณต้องระบุชื่อของฟังก์ชันที่ต้องการเรียก

  1. ไปที่คอนโซล Firebase ของโปรเจ็กต์ แล้วเปิดรายการเมนู Functions ในส่วน Build
  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 []
      }
    }
    

เชื่อมต่อ UI

หากต้องการอนุญาตให้ผู้ใช้ค้นหาโน้ต คุณจะต้องติดตั้งใช้งานแถบค้นหาในหน้าจอรายการโน้ต เมื่อผู้ใช้พิมพ์ข้อความค้นหา คุณต้องเรียกใช้เมธอด performQuery ที่คุณติดตั้งใช้งานในขั้นตอนก่อนหน้า ตัวแก้ไขมุมมอง searchable และ task จาก SwiftUI ทำให้ต้องใช้โค้ดเพียง 2 บรรทัดเท่านั้น

  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 (หรือคลิกปุ่ม Run) เพื่อเปิดแอปในเครื่องจำลอง iOS
  2. คุณควรเห็นโน้ตเดียวกันกับที่เพิ่มในแอปก่อนหน้านี้ในโค้ดแล็บนี้ รวมถึงโน้ตที่คุณเพิ่มผ่านคอนโซล Firebase
  3. คุณควรเห็นช่องค้นหาที่ด้านบนของรายการโน้ต
  4. พิมพ์คำที่ปรากฏในเอกสารที่คุณเพิ่ม อีกครั้ง การดำเนินการนี้จะได้ผลดีที่สุดสำหรับการค้นหาเชิงความหมาย เช่น "ฉันจะเรียกใช้ Firebase API แบบแอซิงโครนัสจาก Swift ได้อย่างไร" (โดยมีเงื่อนไขว่าโน้ตที่คุณเพิ่มอย่างน้อย 1 รายการมีข้อความที่พูดถึงหัวข้อนี้)
  5. คุณอาจคาดหวังว่าจะเห็นผลการค้นหา แต่มุมมองรายการว่างเปล่าและคอนโซล Xcode แสดงข้อความแสดงข้อผิดพลาดว่า "มีการเรียกฟังก์ชันด้วยอาร์กิวเมนต์ที่ไม่ถูกต้อง"

แอป Notes ที่มีรายการผลลัพธ์ว่างเปล่า

ซึ่งหมายความว่าคุณส่งข้อมูลในรูปแบบที่ไม่ถูกต้อง

วิเคราะห์ข้อความแสดงข้อผิดพลาด

  1. หากต้องการดูว่าเกิดข้อผิดพลาดใดขึ้น ให้ไปที่คอนโซล Firebase
  2. ไปที่ส่วนฟังก์ชัน
  3. ค้นหาฟังก์ชัน ext-firestore-vector-search-queryCallable เปิดเมนูรายการเพิ่มเติมโดยคลิกจุดแนวตั้ง 3 จุด
  4. เลือกดูบันทึกเพื่อไปยังเครื่องมือสำรวจบันทึก
  5. คุณควรเห็นข้อผิดพลาด
Unhandled error ZodError: [
  {
    "code": "invalid_type",
    "expected": "object",
    "received": "string",
    "path": [],
    "message": "Expected object, received string"
  }
]

ซึ่งหมายความว่าคุณส่งข้อมูลในรูปแบบที่ไม่ถูกต้อง

ใช้ประเภทข้อมูลที่ถูกต้อง

หากต้องการดูว่าส่วนขยายต้องการพารามิเตอร์ในรูปแบบใด โปรดดูเอกสารประกอบของส่วนขยาย

  1. ไปที่ส่วนส่วนขยายในคอนโซล Firebase
  2. คลิกจัดการ ->การจัดการการค้นหาเวกเตอร์ด้วยส่วนขยาย 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. ขอแสดงความยินดี

ยินดีด้วยที่ทํา Codelab นี้เสร็จสมบูรณ์

ในโค้ดแล็บนี้ คุณได้เรียนรู้วิธีทำสิ่งต่อไปนี้

  • ตั้งค่าฐานข้อมูล Cloud Firestore ที่เปิดใช้การค้นหาเชิงความหมาย
  • สร้างแอป SwiftUI ง่ายๆ เพื่อโต้ตอบกับฐานข้อมูล
  • ใช้แถบค้นหาโดยใช้ตัวแก้ไขมุมมองที่ค้นหาได้และตัวแก้ไขงานของ SwiftUI
  • เรียกใช้ Cloud Function เพื่อค้นหาเชิงความหมายในฐานข้อมูลโดยใช้อินเทอร์เฟซ Callable ของ Firestore SDK

ความรู้ที่ได้รับในโค้ดแล็บนี้จะช่วยให้คุณสร้างแอปพลิเคชันที่มีประสิทธิภาพซึ่งใช้ประโยชน์จากความสามารถในการค้นหาเชิงความหมายของ Cloud Firestore เพื่อมอบประสบการณ์การค้นหาที่ใช้งานง่ายและมีประสิทธิภาพมากขึ้นให้แก่ผู้ใช้

ดูข้อมูลเพิ่มเติมเกี่ยวกับช่องเวกเตอร์ใหม่ของ Firestore และวิธีประมวลผลการฝังเวกเตอร์ได้ในเอกสารประกอบ