Khởi tạo Dữ liệu Chroma Persistent
import { ChromaClient } from 'chromadb'
Khởi tạo Client
const client = new ChromaClient();
Các Thao Tác Thông Thường của Client
await client.reset() // Xoá cơ sở dữ liệu
Làm việc với Bộ Sưu Tập
Chromadb sử dụng khái niệm bộ sưu tập
để quản lý các tập dữ liệu vector, có thể tương đương với các bảng trong MySQL.
Tạo, Xem và Xoá Bộ Sưu Tập
Chroma sử dụng tên bộ sưu tập trong URL, nên có một số hạn chế về việc đặt tên:
- Độ dài tên phải từ 3 đến 63 ký tự.
- Tên phải bắt đầu và kết thúc bằng các chữ thường hoặc số, và có thể chứa dấu chấm, dấu gạch ngang, và gạch dưới ở giữa.
- Tên không được chứa hai dấu chấm liên tiếp.
- Tên không được là một địa chỉ IP hợp lệ.
Để tạo một bộ sưu tập, cần xác định tên bộ sưu tập và một hàm tính toán vector tùy chọn (cũng được gọi là hàm nhúng). Nếu cung cấp một hàm nhúng, nó phải được cung cấp mỗi khi truy cập vào bộ sưu tập.
Lưu ý: Hàm nhúng được sử dụng để tính toán vector của văn bản.
import { ChromaClient } from 'chromadb'
Tạo và tham chiếu đến một bộ sưu tập như sau:
let collection = await client.createCollection({name: "my_collection", embeddingFunction: emb_fn})
let collection2 = await client.getCollection({name: "my_collection", embeddingFunction: emb_fn})
Hàm nhúng nhận văn bản làm đầu vào và trả về dữ liệu vector được tính toán.
Lưu ý: Người mới bắt đầu có thể tìm hiểu về các mô hình nhúng văn bản từ hướng dẫn này.
Các bộ sưu tập hiện có có thể được tham chiếu bằng cách sử dụng .getCollection
theo tên và cũng có thể bị xoá bằng cách sử dụng .deleteCollection
.
const collection = await client.getCollection({name: "tizi365"}) // Tham chiếu đến bộ sưu tập tizi365
await client.deleteCollection({name: "my_collection"}) // Xoá bộ sưu tập
Các Hàm Bộ Sưu Tập Thông Thường
await collection.peek() // Trả về 10 bản ghi dữ liệu đầu tiên trong bộ sưu tập
await collection.count() // Trả về tổng số bản ghi dữ liệu trong bộ sưu tập
Điều Chỉnh Các Phương Pháp Tính Khoảng Cách Vector
createCollection
cũng bao gồm một tham số tùy chọn metadata
, trong đó giá trị của hnsw:space có thể được thiết lập để tùy chỉnh phương pháp tính khoảng cách cho không gian vector.
Lưu ý: Dữ liệu vector biểu thị sự tương đồng giữa các vector bằng cách tính toán khoảng cách không gian giữa chúng, với khoảng cách gần nhau cho thấy sự tương đồng cao và ngược lại.
let collection = client.createCollection("collection_name", undefined, metadata={ "hnsw:space": "cosine" })
Các tùy chọn hợp lệ cho hnsw:space là "l2", "ip", hoặc "cosine". Mặc định là "l2".
Thêm Dữ liệu vào Bộ sưu tập
Sử dụng .add
để thêm dữ liệu vào bộ sưu tập Chroma.
Thêm dữ liệu trực tiếp mà không cần xác định các vector tài liệu:
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", ...],
})
// Giải thích Tham số
// ids - bắt buộc
// embeddings - tùy chọn
// metadata - tùy chọn
// documents - tùy chọn
Nếu Chroma nhận được một danh sách các tài liệu, nó sẽ tự động sử dụng hàm nhúng của bộ sưu tập để tính toán vector cho các tài liệu (nếu không có hàm nhúng nào được cung cấp khi tạo bộ sưu tập, giá trị mặc định sẽ được sử dụng). Chroma cũng sẽ lưu trữ các tài liệu. Nếu một tài liệu quá lớn để sử dụng với hàm nhúng được lựa chọn, ngoại lệ sẽ xảy ra.
Mỗi tài liệu phải có một ID duy nhất (ids). Thêm cùng một ID hai lần sẽ dẫn đến chỉ có giá trị ban đầu được lưu trữ. Một danh sách tùy chọn của từ điển siêu dữ liệu (metadatas) có thể được cung cấp cho mỗi tài liệu để lưu trữ thông tin bổ sung để lọc dữ liệu trong các truy vấn.
Ngoài ra, bạn có thể trực tiếp cung cấp một danh sách dữ liệu vector liên quan đến tài liệu và Chroma sẽ sử dụng dữ liệu vector mà bạn cung cấp mà không cần tính toán vector một cách tự động.
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", ...],
})
Nếu chiều dài của dữ liệu vector cung cấp (kích thước) không khớp với kích thước của bộ sưu tập, một ngoại lệ sẽ xảy ra.
Bạn cũng có thể lưu trữ tài liệu ở nơi khác và chỉ cần cung cấp dữ liệu vector và danh sách siêu dữ liệu đến Chroma. Bạn có thể sử dụng ids để liên kết các vector với các tài liệu được lưu trữ ở nơi khác.
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"}, ...],
})
Ghi chú: Chức năng cốt lõi của cơ sở dữ liệu vector là tìm kiếm tương đồng ngữ nghĩa dựa trên dữ liệu vector. Để giảm kích thước của cơ sở dữ liệu vector và cải thiện hiệu suất, chúng ta có thể chọn lựa lưu trữ dữ liệu vector và một số điều kiện thuộc tính có thể lọc trong cơ sở dữ liệu vector. Dữ liệu khác, như nội dung bài viết, có thể được lưu trữ trong cơ sở dữ liệu như MYSQL, miễn là chúng được kết hợp thông qua các ID.
Truy vấn Dữ liệu Bộ sưu tập
Phương thức .query
có thể được sử dụng để truy vấn tập dữ liệu Chroma theo nhiều cách khác nhau.
Bạn có thể truy vấn bằng cách sử dụng một tập hợp query_embeddings (dữ liệu vector).
Mẹo: Để có được query_embeddings, trong các kịch bản phát triển thực tế, truy vấn của người dùng thường được tính toán trước thành một vector truy vấn thông qua một mô hình nhúng văn bản, sau đó vector này được sử dụng để truy vấn nội dung tương tự.
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"},
})
// thứ tự đầu vào
// query_embeddings - tùy chọn
// n_results - bắt buộc
// where - tùy chọn
// query_texts - tùy chọn
Truy vấn sẽ trả về n_results kết quả hàng đầu cho mỗi vector truy vấn (query_embedding) theo thứ tự. Một bộ lọc where tùy chọn có thể được cung cấp để lọc kết quả dựa trên metadata được liên kết với mỗi tài liệu. Ngoài ra, có thể cung cấp một bộ lọc where_document tùy chọn để lọc kết quả dựa trên nội dung tài liệu.
Nếu query_embeddings được cung cấp không nhất quán với số chiều của bộ sưu tập, sẽ xảy ra một ngoại lệ. Để đảm bảo tính nhất quán của vector, khuyến nghị sử dụng cùng một mô hình nhúng văn bản để tính toán vector.
Bạn cũng có thể truy vấn bằng cách sử dụng một tập hợp các văn bản truy vấn. Chroma sẽ trước tiên tính toán vector cho mỗi văn bản truy vấn bằng cách sử dụng hàm nhúng của bộ sưu tập, sau đó thực hiện truy vấn bằng cách sử dụng các vector văn bản được tạo ra.
await collection.query({
nResults: 10, // n_results
where: {"metadata_field": "is_equal_to_this"}, // where
queryTexts: ["doc10", "thus spake zarathustra", ...], // query_text
})
Bạn cũng có thể sử dụng .get
để truy vấn dữ liệu từ bộ sưu tập theo id.
await collection.get({
ids: ["id1", "id2", "id3", ...], //ids
where: {"style": "style1"} // where
})
.get
cũng hỗ trợ bộ lọc where
và where_document
. Nếu không cung cấp id
, nó sẽ trả về tất cả dữ liệu trong bộ sưu tập phù hợp với các bộ lọc where
và where_document
.
Xác định Các Trường Trả về
Khi sử dụng get
hoặc query
, bạn có thể sử dụng tham số include
để xác định các trường dữ liệu cần trả về, bao gồm dữ liệu vector, tài liệu và bất kỳ dữ liệu nào trong metadata. Mặc định, Chroma trả về tài liệu, metadata và khoảng cách vector. Bạn có thể xác định các trường cần trả về bằng cách truyền một mảng tên trường cho tham số includes của get hoặc query.
collection.get(
include=["documents"]
)
collection.query(
query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],
include=["documents"]
)
Sử Dụng Bộ Lọc Where
Chroma hỗ trợ việc lọc các truy vấn dựa trên metadata và nội dung tài liệu. Bộ lọc where
được sử dụng để lọc metadata, và bộ lọc where_document
được sử dụng để lọc nội dung tài liệu. Dưới đây, chúng tôi giải thích cách viết biểu thức điều kiện lọc.
Lọc theo Metadata
Để lọc metadata, một từ điển bộ lọc where phải được cung cấp cho truy vấn. Từ điển phải có cấu trúc sau:
{
"metadata_field": {
<Toán_tử>: <Giá_trị>
}
}
Lọc metadata hỗ trợ các toán tử sau:
- $eq - Bằng (chuỗi, số nguyên, số thực)
- $ne - Không bằng (chuỗi, số nguyên, số thực)
- $gt - Lớn hơn (số nguyên, số thực)
- $gte - Lớn hơn hoặc bằng (số nguyên, số thực)
- $lt - Nhỏ hơn (số nguyên, số thực)
- $lte - Nhỏ hơn hoặc bằng (số nguyên, số thực)
Sử dụng toán tử $eq tương đương với việc sử dụng bộ lọc where.
{
"metadata_field": "chuỗi_tìm_kiếm"
}
{
"metadata_field": {
"$eq": "chuỗi_tìm_kiếm"
}
}
Lọc Nội dung Tài liệu
Để lọc nội dung tài liệu, một từ điển bộ lọc where_document phải được cung cấp cho truy vấn. Từ điển phải có cấu trúc sau:
{
"$contains": "chuỗi_tìm_kiếm"
}
Sử dụng toán tử logic
Bạn cũng có thể sử dụng các toán tử logic $and
và $or
để kết hợp nhiều bộ lọc.
Toán tử $and
sẽ trả về kết quả khớp với tất cả các bộ lọc trong danh sách.
{
"$and": [
{
"metadata_field": {
<Operator>: <Value>
}
},
{
"metadata_field": {
<Operator>: <Value>
}
}
]
}
Toán tử $or
sẽ trả về kết quả khớp với bất kỳ điều kiện lọc nào trong danh sách.
{
"$or": [
{
"metadata_field": {
<Operator>: <Value>
}
},
{
"metadata_field": {
<Operator>: <Value>
}
}
]
}
Cập nhật dữ liệu
Chroma cũng hỗ trợ thao tác upsert, có thể cập nhật dữ liệu hiện có và chèn dữ liệu mới nếu dữ liệu chưa tồn tại.
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"]
})
Xóa dữ liệu
Chroma hỗ trợ sử dụng .delete để xóa dữ liệu từ bộ sưu tập theo id.
await collection.delete({
ids: ["id1", "id2", "id3",...], //ids
where: {"chapter": "20"} //where
})