Hướng dẫn chi tiết về phát triển Chromadb Python

Cài đặt

pip install chromadb

Lưu trữ Dữ liệu Chromadb

import chromadb

Bạn có thể chỉ định đường dẫn lưu trữ cho tệp cơ sở dữ liệu Chroma. Nếu dữ liệu tồn tại, tệp cơ sở dữ liệu s

Thêm Dữ liệu vào Bộ sưu tập

Sử dụng phương thức .add để thêm dữ liệu vào Chroma.

Thêm dữ liệu trực tiếp mà không cần chỉ định vector của tài liệu:

collection.add(
    documents=["lorem ipsum...", "doc2", "doc3", ...],
    metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],
    ids=["id1", "id2", "id3", ...]
)

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 vectors 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 tài liệu quá lớn để tính toán bằng cách sử dụng hàm nhúng được chọn, một 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 ID hai lần sẽ dẫn đến việc lưu trữ giá trị ban đầu một lần duy nhất. Theo tùy chọn, bạn cũng có thể cung cấp một danh sách các từ điển dữ liệu phụ (metadatas) cho mỗi tài liệu, để lưu trữ thông tin bổ sung có thể được sử dụng để lọc dữ liệu trong quá trình truy vấn.

Một cách khác, bạn có thể cung cấp trực tiếp một danh sách các vector dữ liệu liên quan đến tài liệu, và Chroma sẽ sử dụng vector dữ liệu mà bạn cung cấp mà không tự động tính toán các vectors.

collection.add(
    documents=["doc1", "doc2", "doc3", ...],
    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"}, ...],
    ids=["id1", "id2", "id3", ...]
)

Nếu số chiều dữ liệu vector cung cấp không khớp với số chiều 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ữ các tài liệu ở nơi khác và cung cấp cho Chroma dữ liệu vector và danh sách siêu dữ liệu. Bạn có thể sử dụng ids để liên kết các vectors với các tài liệu được lưu trữ ở nơi khác.

collection.add(
    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"}, ...],
    ids=["id1", "id2", "id3", ...]
)

Lưu ý: 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ố thuộc tính lọc cần thiết trong cơ sở dữ liệu vector. Dữ liệu khác, chẳng hạn như nội dung bài viết, có thể được lưu trữ trong các cơ sở dữ liệu như MYSQL, miễn là chúng được liên kết 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 các query_embeddings (dữ liệu vector).

Mẹo: Trong các kịch bản phát triển thực tế, query_embeddings thường được thu được bằng cách tính toán vector của truy vấn của người dùng thông qua một mô hình nhúng văn bản, sau đó sử dụng vector này để truy vấn nội dung tương tự.

collection.query(
    query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],
    n_results=10,
    where={"metadata_field": "is_equal_to_this"},
    where_document={"$contains":"search_string"}
)

Truy vấn sẽ trả về kết quả n_results tốt nhất phù hợp với mỗi vector truy vấn (query_embedding) theo thứ tự. Một từ điển bộ lọc where tùy chọn có thể được cung cấp để lọc kết quả dựa trên siêu dữ liệu liên kết với mỗi tài liệu. Ngoài ra, một từ điển bộ lọc where_document tùy chọn có thể được cung cấp để 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 chiều của bộ sưu tập, một ngoại lệ sẽ xảy ra. Để đảm bảo kích thước vector nhất quán, hãy 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ẽ đầu 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.

collection.query(
    query_texts=["doc10", "thus spake zarathustra", ...],
    n_results=10,
    where={"metadata_field": "is_equal_to_this"},
    where_document={"$contains":"search_string"}
)

Bạn cũng có thể sử dụng .get để truy vấn dữ liệu từ bộ sưu tập theo id.

collection.get(
    ids=["id1", "id2", "id3", ...],
    where={"style": "style1"}
)

.get cũng hỗ trợ bộ lọc where và where_document. Nếu không có id nào được cung cấp, nó sẽ trả về tất cả các mục trong bộ sưu tập phù hợp với các bộ lọc where và where_document.

Xác định 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 dữ liệu cần trả về--embeddings, documents, hoặc metadatas, và cho truy vấn, dữ liệu khoảng cách cần phải được trả về. Theo mặc định, Chroma trả về tài liệu và siêu dữ liệu, và trả về dữ liệu khoảng cách cho các truy vấn, trong khi "ids" luôn trả về. Bạn có thể xác định các trường cần trả bằng cách truyền một mảng tên trường vào tham số includes của phương thức query hoặc get.

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ợ lọc truy vấn dựa trên siêu dữ liệu và nội dung tài liệu. Bộ lọc where được sử dụng để lọc siêu dữ liệu, và bộ lọc where_document được sử dụng để lọc nội dung tài liệu, và dưới đây là cách viết biểu thức điều kiện bộ lọc.

Lọc theo Siêu dữ liệu

Để lọc siêu dữ liệu, bạn phải cung cấp một từ điển bộ lọc where cho truy vấn. Từ điển phải có cấu trúc sau:

{
    "metadata_field": {
        <Operator>: <Value>
    }
}

Lọc siêu dữ liệu 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": "search_string"
}

{
    "metadata_field": {
        "$eq": "search_string"
    }
}

Lọc Nội dung tài liệu

Để lọc nội dung tài liệu, bạn phải cung cấp một từ điển bộ lọc where_document cho truy vấn. Từ điển phải có cấu trúc sau:

{
    "$contains": "search_string"
}

Sử dụng Toán Tử Logic

Bạn cũng có thể sử dụng các toán tử logic $and$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 trong Bộ Sưu Tập

Sử dụng .update cho phép bạn cập nhật bất kỳ thuộc tính nào của dữ liệu trong bộ sưu tập.

collection.update(
    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", ...],
)

Nếu một id không được tìm thấy trong bộ sưu tập, một lỗi sẽ được ghi lại và việc cập nhật sẽ bị bỏ qua. Nếu tài liệu cung cấp không có một vector tương ứng, hàm nhúng của bộ sưu tập sẽ được sử dụng để tính toán vector.

Nếu dữ liệu vector cung cấp có kích thước khác nhau so với bộ sưu tập, một ngoại lệ sẽ xảy ra.

Chroma cũng hỗ trợ thao tác upsert, mà có thể cập nhật dữ liệu hiện có và chèn dữ liệu mới nếu nó không tồn tại.

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 trong Bộ Sưu Tập

Chroma hỗ trợ sử dụng .delete để xóa dữ liệu từ bộ sưu tập theo id. Các vector, tài liệu và siêu dữ liệu liên quan đến mỗi dữ liệu cũng sẽ bị xóa.

collection.delete(
    ids=["id1", "id2", "id3",...],
    where={"chapter": "20"}
)

.delete cũng hỗ trợ một bộ lọc where. Nếu không cung cấp id, nó sẽ xóa tất cả các mục trong bộ sưu tập khớp với bộ lọc where.