กำลังเริ่มต้นข้อมูล Chroma ที่ต้องการจำ
import { ChromaClient } from 'chromadb'
เริ่มต้นการใช้งาน Client
const client = new ChromaClient();
การดำเนินการทั่วไปของ Client
await client.reset() // ล้างฐานข้อมูล
การทำงานกับคอลเล็กชัน
Chromadb ใช้แนวคิดของ collection
เพื่อการจัดการเซ็ตข้อมูลเวกเตอร์ ซึ่งสามารถเปรียบเทียบกับตารางใน MySQL
การสร้าง ดู และลบคอลเล็กชัน
Chroma ใช้ชื่อคอลเล็กชันใน URL ดังนั้นมีข้อจำกัดในการตั้งชื่อ:
- ความยาวของชื่อต้องอยู่ระหว่าง 3 และ 63 ตัวอักษร
- ชื่อต้องเริ่มต้นและลงท้ายด้วยตัวอักษรเล็กหรือตัวเลข และสามารถมีจุด ขีดล่าง และขีดล่าง ระหว่าง
- ชื่อไม่สามารถมีสองจุดต่อกัน
- ชื่อไม่สามารถเป็นที่อยู่ IP ที่ถูกต้อง
เพื่อสร้างคอลเล็กชัน จำเป็นต้องระบุชื่อคอลเล็กชันและฟังก์ชันการคำนวณเวกเตอร์ตัวเลือก (เรียกว่าฟังก์ชันฝังตัวเลือก) หากให้ฟังก์ชันฝังตัวเลือก จำเป็นต้องกำหนดทุกครั้งที่เข้าถึงคอลเล็กชัน
หมายเหตุ: ฟังก์ชันฝังตัวเลือกใช้สำหรับคำนวณเวกเตอร์ของข้อความ
import { ChromaClient } from 'chromadb'
สร้างและอ้างอิงคอลเล็กชันดังต่อไปนี้:
let collection = await client.createCollection({name: "my_collection", embeddingFunction: emb_fn})
let collection2 = await client.getCollection({name: "my_collection", embeddingFunction: emb_fn})
ฟังก์ชันฝังตัวเลือกรับข้อความเป็นอินพุตและส่งคืนข้อมูลเวกเตอร์ที่คำนวณ
หมายเหตุ: ผู้เริ่มต้นสามารถเรียนรู้เกี่ยวกับโมเดลฝังตัวข้อความจาก บทเรียนนี้
คอลเล็กชันที่มีอยู่สามารถถูกอ้างอิงโดยใช้ .getCollection
ตามชื่อ และยังสามารถถูกลบโดยใช้ .deleteCollection
const collection = await client.getCollection({name: "tizi365"}) // อ้างถึงคอลเล็กชัน tizi365
await client.deleteCollection({name: "my_collection"}) // ลบคอลเล็กชัน
ฟังก์ชันคอลเล็กชันที่สามารถใช้ในการดำเนินการทั่วไป
await collection.peek() // ส่งคืนบันทึกข้อมูล 10 รายการแรกในคอลเล็กชัน
await collection.count() // ส่งคืนจำนวนบันทึกข้อมูลทั้งหมดในคอลเล็กชัน
การปรับเปลี่ยนวิธีคำนวณระยะห่างของเวกเตอร์
createCollection
ยังรวมพารามิเตอร์ metadata
ที่สามารถตั้งค่า hnsw:space เพื่อปรับแต่งวิธีคำนวณระยะห่างสำหรับเวกเตอร์
หมายเหตุ: ข้อมูลเวกเตอร์แสดงถึงความคล้ายคลึงระหว่างเวกเตอร์โดยคำนวณระยะทางทางเชิงพื้นที่ระหว่างพวกเขา โดยระยะทางที่ใกล้ทำให้ความคล้ายคลึงสูง และกลับกัน
let collection = client.createCollection("collection_name", undefined, metadata={ "hnsw:space": "cosine" })
ตัวเลือกที่ถูกต้องสำหรับ hnsw:space มี "l2", "ip", หรือ "cosine" ค่าเริ่มต้นคือ "l2"
เพิ่มข้อมูลลงในคอลเลคชัน
ใช้ .add
เพื่อเพิ่มข้อมูลลงในคอลเลคชันของ Chroma
เพิ่มข้อมูลโดยตรงโดยไม่ระบุเวกเตอร์ของเอกสาร:
await collection.add({
ids: ["id1", "id2", "id3", ...],
metadatas: [{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],
documents: ["lorem ipsum...", "doc2", "doc3", ...],
})
// อธิบายพารามิเตอร์
// ids - จำเป็น
// embeddings - ไม่จำเป็น
// metadata - ไม่จำเป็น
// documents - ไม่จำเป็น
หาก Chroma ได้รับรายการของเอกสาร จะใช้ฟังก์ชันเวกเตอร์ของคอลเลคชันโดยอัตโนมัติเพื่อคำนวณเวกเตอร์ของเอกสาร (หากไม่ได้ระบุฟังก์ชันเวกเตอร์เมื่อสร้างคอลเลคชัน ค่าเริ่มต้นจะถูกใช้) Chroma ยังจะเก็บเอกสารเองเช่นกัน หากเอกสารมีขนาดใหญ่เกินไปที่จะใช้กับฟังก์ชันเวกเตอร์ที่ถูกเลือก เกิดข้อยกเว้นจะเกิดขึ้น
ทุกเอกสารจะต้องมี ID ที่ไม่ซ้ำกัน (ids) เพิ่ม ID เดียวกันสองครั้งจะทำให้ค่าเริ่วต้นถูกเก็บไว้เท่านั้น เราสามารถระบุรายการทางอเมตาดาต้าเพิ่มเติมสำหรับแต่ละเอกสารเพื่อเก็บข้อมูลเพิ่มเติมสำหรับการกรองข้อมูลในการค้นหา
โดยอนไล คุณสามารถระบุรายการของเวกเตอร์ที่เกี่ยวข้องกับเอกสารโดยตรง และ Chroma จะใช้ข้อมูลเวกเตอร์ที่คุณระบุโดยไม่คำนวณเวกเตอร์โดยอัต็อมค่า
await collection.add({
ids: ["id1", "id2", "id3", ...],
embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],
metadatas: [{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],
documents: ["lorem ipsum...", "doc2", "doc3", ...],
})
หากมิตรงกับขนาดของข้อมูลเวกเตอร์ที่ระบุ ตัวเลือกข้อยกเว้นจะเกิดขึ้น
คุณสามารถจัดเก็บเอกสารที่อยู่ในที่อื่นและเพียงแค่ระบุข้อมูลเวกเตอร์และรายการข้อมูลเพิ่มเติมเพื่อเก็บเข้าไปยัง Chroma คุณสามารถใช้ IDs เพื่อแปลงเวกเตอร์กับเอกสารที่เก็บไว้ที่อื่น
await collection.add({
ids: ["id1", "id2", "id3", ...],
embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2], ...],
metadatas: [{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],
})
หมายเหตุ: ฟังก์ชันหลักของฐานข้อมูลเวกเตอร์คือการค้นหาความคล้ายคลึงแบบดัจรัสโดยใช้ข้อมูลเวกเตอร์ เพื่อลดขนาดของฐานข้อมูลเวกเตอร์และปรับปรุงประสิทธิภาพ เราสามารถเลือกที่จะเก็บข้อมูลเวคเตอร์และเงื่อนไขการคัดกรองบางอย่างในฐานข้อมูลเวกเตอร์ เนื่องจากเงื่อนไขอื่นๆ เช่น เนื้อหาบทความสามารถเก็บไว้ในฐานข้อมูลเช่น MySQL และถือเป็นผูกพันกับ IDs
การค้นหาข้อมูลในคอลเล็กชัน
เมธอด .query
สามารถใช้ในการค้นหาชุดข้อมูลของชุดข้อมูล Chroma ในหลายวิธี
คุณสามารถค้นหาโดยใช้ query_embeddings (ข้อมูลเวกเตอร์)
เกร็ด: เพื่อให้ได้ query_embeddings ในสถานการณ์การพัฒนาจริง ๆ บางที คำค้นของผู้ใช้จะถูกคำนวณก่อนเป็นเวกเตอร์คำค้นผ่านโมเดล text embedding และจากนั้นเวกเตอร์นี้จะถูกใช้ในการค้นหาเนื้อหาที่คล้ายกัน
const result = await collection.query({
queryEmbeddings: [[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],
nResults: 10,
where: {"metadata_field": "is_equal_to_this"},
})
// ลำดับการป้อน
// query_embeddings - ไม่บังคับ
// n_results - จำเป็น
// where - ไม่บังคับ
// query_texts - ไม่บังคับ
การค้นหาจะส่งคืนผลลัพธ์ n_results ที่ดีที่สุดสำหรับแต่ละเวกเตอร์คำค้น (query_embedding) ตามลำดับ สามารถให้ได้เงื่อนไขกรอง where ในรูปแบบของพจนานุกรมสามารถให้ได้เงื่อนไขกรอง where_document ในรูปแบบของพจนานุกรม เพิ่มเติม และสามารถให้ได้เงื่อนไขกรอง where_document ในรูปแบบของพจนานุกรมเพื่อกรองผลลัพธ์ตามเนื้อหาของเอกสาร
หาก query_embeddings ที่ให้กับฟังก์ชันไม่สอดคล้องกับมิติของคอลเล็กชัน จะเกิดข้อยกเว้นขึ้น หากต้องการให้มีความสอดคล้องของเวกเตอร์ ขอแนะนำให้ใช้โมเดล text embedding เดียวกันในการคำนวณเวกเตอร์
คุณยังสามารถค้นหาโดยใช้เซ็ตของข้อความคำค้น Chroma จะคำนวณเวกเตอร์สำหรับแต่ละข้อความคำค้นโดยใช้ฟังก์ชันฝังหลังของคอลเล็กชัน และจากนั้นดำเนินการค้นหาโดยใช้เวกเตอร์ข้อความที่สร้างขึ้น
await collection.query({
nResults: 10, // n_results
where: {"metadata_field": "is_equal_to_this"}, // where
queryTexts: ["doc10", "thus spake zarathustra", ...], // query_text
})
คุณยังสามารถใช้ .get
เพื่อค้นหาข้อมูลจากคอลเล็กชันตาม id
await collection.get({
ids: ["id1", "id2", "id3", ...], //ids
where: {"style": "style1"} // where
})
.get
ยังสนับสนุน where
และ where_document
filters หากไม่มี id
ที่ให้ จะส่งคืนข้อมูลทั้งหมดในคอลเล็กชันที่ตรงกับ where
และ where_document
filters
การระบุฟิลด์ที่จะส่งคืน
เมื่อใช้ get
หรือ query
คุณสามารถใช้พารามิเตอร์ include
เพื่อระบุฟิลด์ข้อมูลที่จะส่งคืน รวมถึงข้อมูลเวกเตอร์ เอกสาร และข้อมูลใด ๆ ใน metadata โดยค่าเริ่มต้น Chroma จะส่งคืนเอกสาร metadata และระยะทางของเวกเตอร์ คุณสามารถระบุฟิลด์ที่จะส่งคืนโดยการส่งอาร์เรย์ของชื่อฟิลด์ที่เป็นค่าเพิ่มเติมไปยังพารามิเตอร์ includes
ของ get หรือ query
collection.get(
include=["documents"]
)
collection.query(
query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],
include=["documents"]
)
การใช้กรอง where
Chroma สนับสนุนการกรองคำค้นข้อมูลโดยใช้ metadata และเนื้อหาของเอกสาร การกรองโดยใช้ where
ใช้สำหรับการกรองเมตาดาต้า และการกรองโดยใช้ where_document
ใช้สำหรับการกรองเนื้อหาของเอกสาร ข้างล่างเป็นการอธิบายวิธีเขียนเงื่อนไขของกรอง
การกรองโดยใช้เมตาดาต้า
เพื่อกรองเมตาดาต้า จำเป็นต้องมีพจนานุกรมกรอง where สำหรับคำค้น เพจนานุกรมจำเป็นต้องมีโครงสร้างดังต่อไปนี้
{
"metadata_field": {
<Operator>: <Value>
}
}
การกรองเมตาดาต้าสนับสนุนตัวดำเนินการต่อไปนี้:
- $eq - เท่ากับ (string, integer, float)
- $ne - ไม่เท่ากับ (string, integer, float)
- $gt - มากกว่า (int, float)
- $gte - มากกว่าหรือเท่ากับ (int, float)
- $lt - น้อยกว่า (integer, float)
- $lte - น้อยกว่าหรือเท่ากับ (int, float)
การใช้ตัวดำเนินการ $eq เทียบเท่ากับการใช้กรอง where
{
"metadata_field": "search_string"
}
{
"metadata_field": {
"$eq": "search_string"
}
}
การกรองเนื้อหาของเอกสาร
เพื่อกรองเนื้อหาของเอกสาร จำเป็นต้องมีพจนานุกรมกรอง where_document สำหรับคำค้น เพจนานุกรมจำเป็นต้องมีโครงสร้างดังต่อไปนี้
{
"$contains": "search_string"
}
การใช้ตัวดำเนินการตรรกะ
คุณยังสามารถใช้ตัวดำเนินการตรรกะ $and
และ $or
เพื่อรวมตัวกรองหลายรายการเข้าด้วยกัน
ตัวดำเเนินการ $and
จะส่งคืนผลลัพธ์ที่ตรงกับทุกตัวกรองในรายการ
{
"$and": [
{
"metadata_field": {
<Operator>: <Value>
}
},
{
"metadata_field": {
<Operator>: <Value>
}
}
]
}
ตัวดำเเนินการ $or
จะส่งคืนผลลัพธ์ที่ตรงกับเงื่อนไขการกรองใดก็ได้ในรายการ
{
"$or": [
{
"metadata_field": {
<Operator>: <Value>
}
},
{
"metadata_field": {
<Operator>: <Value>
}
}
]
}
การอัพเดตข้อมูล
Chroma ยังรองรับการดำเนินการ upsert ซึ่งสามารถอัพเดตข้อมูลที่มีอยู่และแทรกข้อมูลใหม่หากข้อมูลยังไม่มีอยู่
await collection.upsert({
ids: ["id1", "id2", "id3"],
embeddings: [[1.1, 2.3, 3.2], [4.5, 6.9, 4.4], [1.1, 2.3, 3.2]],
metadatas: [{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}],
documents: ["doc1", "doc2", "doc3"]
})
การลบข้อมูล
Chroma รองรับการใช้ .delete เพื่อลบข้อมูลจากคอลเลคชันโดยใช้รหัส
await collection.delete({
ids: ["id1", "id2", "id3",...], //ids
where: {"chapter": "20"} //where
})