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

1. ภาพรวม

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

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

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

สิ่งที่คุณต้องมี

  • Xcode 15.3
  • โค้ดตัวอย่างของ Codelab ซึ่งจะดาวน์โหลดได้ในขั้นตอนถัดไปของ Codelab

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

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

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

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

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

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

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

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

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

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

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

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

ตั้งค่า Cloud Firestore

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

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

3. เชื่อมต่อแอปบนอุปกรณ์เคลื่อนที่

ในส่วนนี้ของ Codelab คุณจะดาวน์โหลดซอร์สโค้ดสำหรับแอปจดโน้ตแบบง่ายๆ และเชื่อมต่อกับโปรเจ็กต์ 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. หากต้องการ คุณสามารถป้อนชื่อเล่นแอป (หมายเหตุสำหรับ 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 Simulator ในรายการแบบเลื่อนลงเรียกใช้ปลายทาง ให้เลือกเครื่องมือจำลอง iOS ก่อนการเลือกเครื่องมือจำลอง iOS ในรายการแบบเลื่อนลงของการเรียกใช้ปลายทาง
  2. จากนั้นคลิกปุ่มเรียกใช้ หรือกด ⌘ + R
  3. หลังจากเปิดแอปในเครื่องมือจำลองสำเร็จแล้ว ให้เพิ่มหมายเหตุอีก 2 ข้อ
  4. ในคอนโซล Firebase ให้ไปที่เบราว์เซอร์ข้อมูล Firestore เพื่อดูเอกสารใหม่ที่กำลังสร้างขึ้นขณะที่เพิ่มโน้ตใหม่ในแอปคอนโซล Cloud Firestore ที่แสดงเอกสารบางส่วน พร้อมด้วยเครื่องมือจำลอง iOS ที่แสดงเอกสารเดียวกัน

4. ติดตั้ง Vector Search ที่มีส่วนขยาย Firestore

ในส่วนนี้ของ Codelab คุณจะติดตั้งส่วนขยาย Vector Search ที่มีส่วนขยาย Firestore และกำหนดค่าตามข้อกำหนดของแอปจดโน้ตที่คุณใช้งานอยู่

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

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

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

Firebase Extensions ใช้ประโยชน์จาก Cloud Functions for Firebase ซึ่งกำหนดให้โปรเจ็กต์ต้องอยู่ในแพ็กเกจ Blaze ในแบบจ่ายเมื่อใช้ ก่อนที่จะใช้ Vector Search กับส่วนขยาย Firestore คุณต้องอัปเกรดโปรเจ็กต์ก่อน

  1. คลิกอัปเกรดโปรเจ็กต์เพื่อดำเนินการต่อ อัปเกรดโปรเจ็กต์เป็นแผน Blaze
  2. เลือกบัญชีสำหรับการเรียกเก็บเงินที่มีอยู่ หรือสร้างบัญชีใหม่ คลิกต่อไปการเลือกบัญชีสำหรับการเรียกเก็บเงิน
  3. ตั้งงบประมาณ (เช่น 100 THB) คลิกต่อไป แล้วคลิกซื้อการตั้งค่างบประมาณ
  4. ตรวจสอบว่าเปิดใช้ API และสร้างทรัพยากรแล้วการตรวจสอบ API ที่เปิดใช้
  5. เปิดใช้บริการที่จำเป็นการเปิดใช้บริการที่จำเป็น
  6. เมื่อเปิดใช้ Cloud Storage ให้เลือกโหมดทดสอบกฎความปลอดภัย
  7. ยืนยันว่า Cloud Storage จะใช้ตำแหน่งเดียวกับอินสแตนซ์ Cloud Firestore
  8. เมื่อเปิดใช้บริการทั้งหมดแล้ว ให้คลิก Nextคลิก "ถัดไป" หลังจากเปิดใช้บริการทั้งหมด
  9. ตรวจสอบสิทธิ์เข้าถึงที่มอบให้ส่วนขยายนี้
  10. กำหนดค่าส่วนขยาย:
    • เลือก Vertex AI เป็น LLM
    • เส้นทางการรวบรวมข้อมูล: โน้ต
    • ขีดจำกัดข้อความค้นหาเริ่มต้น: 3
    • ชื่อช่องอินพุต: text
    • ชื่อฟิลด์เอาต์พุต: การฝัง
    • ชื่อช่องสถานะ:* *สถานะ*
    • ฝังเอกสารที่มีอยู่: ใช่
    • อัปเดตเอกสารที่มีอยู่: ใช่
    • ตำแหน่งของ Cloud Function: us-central1
  11. คลิกติดตั้งส่วนขยายเพื่อดำเนินการติดตั้งให้เสร็จสิ้น

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

5. ความเป็นมา

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

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

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

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

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

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

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

ก่อนที่จะใช้ส่วนขยาย Vector Search ที่มีส่วนขยาย Firestore ในแอป iOS ที่คุณดาวน์โหลดก่อนหน้านี้ใน Codelab คุณจะลองใช้ส่วนขยายได้ในคอนโซล Firebase

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

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

  1. เมื่อติดตั้งส่วนขยายเสร็จแล้ว ให้คลิกปุ่มเริ่มต้นใช้งาน หน้าภาพรวมของส่วนขยาย Firebase ในคอนโซล 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 ส่วนขยายน่าจะประมวลผลการฝังสำหรับเอกสารโน้ตทั้งหมดที่สร้างไว้ในขั้นตอนก่อนหน้าใน Codelab นี้เสร็จเรียบร้อยแล้วการกำหนดค่าดัชนีภายในคอนโซล 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. ใน Cloud Log Explorer คุณควรเห็นข้อความแสดงข้อผิดพลาด "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. คัดลอกรหัส 1 รายการและกลับไปที่คอลเล็กชัน notes
  13. ใช้ ⌘+F เพื่อค้นหารหัสเอกสารที่คุณคัดลอก เอกสารนี้คือรหัสที่ตรงกับการค้นหาของคุณมากที่สุดค้นหารหัสเอกสารในรายการเอกสาร

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

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

เชื่อมต่อฟังก์ชันที่เรียกได้เพื่อดำเนินการค้นหา

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

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

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

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

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

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

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

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

  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 นี้สำเร็จแล้ว

คุณได้เรียนรู้วิธีต่อไปนี้ใน Codelab

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

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

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