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

1. ภาพรวม

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

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

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

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

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

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

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

ตั้งค่า Cloud Firestore

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

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

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

ตั้งค่า Cloud Storage for 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. คุณป้อนชื่อเล่นแอปได้หากต้องการ (หมายเหตุสำหรับ 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 ในคอนโซล Firestore
  2. คลิกสำรวจ Extensions Hubแท็บ 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. คลิกติดตั้งส่วนขยายเพื่อสิ้นสุดการติดตั้ง

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

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 อื่นเพื่อคํานวณการฝัง เอกสารประกอบสําหรับการค้นหาเวกเตอร์ด้วยส่วนขยาย 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 และใช้งานฟีเจอร์การค้นหาเชิงความหมายที่จะช่วยให้ผู้ใช้ค้นหาโน้ตโดยใช้การค้นหาด้วยภาษาที่เป็นธรรมชาติ

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

ส่วนขยายการค้นหาเวกเตอร์ที่มี Firestore มีฟังก์ชัน Cloud ที่คุณเรียกใช้จากแอปบนอุปกรณ์เคลื่อนที่เพื่อค้นหาดัชนีที่คุณสร้างขึ้นก่อนหน้านี้ในโค้ดแล็บนี้ได้ ในขั้นตอนนี้ คุณจะต้องสร้างการเชื่อมต่อระหว่างแอปบนอุปกรณ์เคลื่อนที่กับฟังก์ชันที่เรียกใช้ได้นี้ 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 มีให้ทำให้คุณเขียนโค้ดได้เพียงไม่กี่บรรทัด

  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 Functions เพื่อทำการค้นหาเชิงความหมายในฐานข้อมูลโดยใช้อินเทอร์เฟซ Callable ของ Firestore SDK

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

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