永続的なクロマデータの初期化

import { ChromaClient } from 'chromadb'

クライアントの初期化

const client = new ChromaClient();

一般的なクライアント操作

await client.reset() // データベースをクリア

コレクションの操作

Chromadbはベクトルデータのセットを管理するために collection の概念を使用しており、これはMySQLのテーブルに似ています。

コレクションの作成、表示、削除

Chromaでは、URLでコレクション名が使用されるため、いくつかの命名規則があります:

  • 名前の長さは3から63文字の間でなければなりません。
  • 名前は小文字または数字で始まり、終わる必要があり、また、その間にはピリオド、ハイフン、アンダースコアを含めることができます。
  • 名前に連続した2つのピリオドを含めることはできません。
  • 名前は有効な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はドキュメントのリストを受け取ると、(コレクションの作成時に埋め込み関数が指定されていない場合はデフォルト値が使用されます)自動的にコレクションの埋め込み関数を使用してドキュメントのベクトルを計算し、ドキュメント自体も保存します。選択した埋め込み関数で使用できないほど大きなドキュメントの場合、例外が発生します。

各ドキュメントには一意のID(ids)が必要です。同じIDを2回追加すると、最初の値のみが保存されます。クエリ中のデータをフィルタリングするための追加情報を保存するために、各ドキュメントに対してオプションのメタデータ辞書(metadatas)のリストを提供できます。

別の方法として、ドキュメント関連のベクトルデータのリストを直接提供することができ、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などのデータベースに保存してもかまいませんが、IDを介して関連付けられている限りです。

コレクションデータのクエリング

.query メソッドを使用して、Chromaデータセットを複数の方法でクエリできます。

クエリは、クエリ埋め込み(ベクトルデータ)を使用して行うことができます。

ヒント: 実際の開発シナリオでは、ユーザーのクエリは通常最初にテキスト埋め込みモデルを使用してクエリベクトルに計算され、その後このベクトルを使用して類似コンテンツをクエリします。

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 - オプション

クエリは、各クエリベクトル(query_embedding)の上位 n_results 結果を順番に返します。オプションで where フィルター辞書を提供して、各ドキュメントに関連するメタデータに基づいて結果をフィルタリングできます。さらに、オプションで where_document フィルター辞書を提供して、ドキュメントコンテンツに基づいて結果をフィルタリングできます。

提供された query_embeddings がコレクションの次元と一致しない場合、例外が発生します。ベクトルの一貫性を確保するためには、同じテキスト埋め込みモデルを使用することが推奨されています。

クエリテキストのセットを使用してもクエリできます。Chroma では、最初にコレクションの埋め込み関数を使用して各クエリテキストのベクトルを計算し、生成されたテキストベクトルを使用してクエリを実行します。

await collection.query({
    nResults: 10, // n_results
    where: {"metadata_field": "is_equal_to_this"}, // where
    queryTexts: ["doc10", "thus spake zarathustra", ...], // query_text
})

また、.get を使用してコレクションからデータをクエリできます。

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

.getwhere および where_document フィルターもサポートしています。id を指定しない場合、where および where_document フィルターに一致するコレクション内のすべてのデータが返されます。

返されるフィールドの指定

get または query を使用する際に、include パラメータを使用して、返されるデータフィールドを指定できます。デフォルトでは、Chroma はドキュメント、メタデータ、ベクトル距離を返します。get または query の includes パラメータにフィールド名の配列を渡すことで、返されるフィールドを指定できます。

collection.get(
    include=["documents"]
)

collection.query(
    query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2], ...],
    include=["documents"]
)

Where フィルターの使用

Chroma では、メタデータおよびドキュメントコンテンツに基づいてクエリをフィルタリングすることができます。where フィルターはメタデータをフィルタリングするために使用され、where_document フィルターはドキュメントコンテンツをフィルタリングするために使用されます。以下では、フィルタ条件式の書き方について説明します。

メタデータによるフィルタリング

メタデータをフィルタリングするには、クエリのために where フィルター辞書が提供される必要があります。辞書は以下の構造を持つ必要があります。

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

メタデータのフィルタリングは以下のオペレーターをサポートしています:

  • $eq - 一致(文字列、整数、浮動小数点数)
  • $ne - 一致しない(文字列、整数、浮動小数点数)
  • $gt - より大きい(整数、浮動小数点数)
  • $gte - 以上(整数、浮動小数点数)
  • $lt - より小さい(整数、浮動小数点数)
  • $lte - 以下(整数、浮動小数点数)

$eq オペレーターの使用は where フィルターの使用と同等です。

{
    "metadata_field": "search_string"
}


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

ドキュメントコンテンツによるフィルタリング

ドキュメントコンテンツをフィルタリングするには、クエリのために where_document フィルター辞書が提供される必要があります。辞書は以下の構造を持つ必要があります。

{
    "$contains": "search_string"
}

論理演算子の使用

複数のフィルタを組み合わせるために、$and$or の論理演算子を使用することもできます。

$and 演算子は、リスト内のすべてのフィルタに一致する結果を返します。

{
    "$and": [
        {
            "metadata_field": {
                <演算子>: <値>
            }
        },
        {
            "metadata_field": {
                <演算子>: <値>
            }
        }
    ]
}

$or 演算子は、リスト内のいずれかのフィルタ条件に一致する結果を返します。

{
    "$or": [
        {
            "metadata_field": {
                <演算子>: <値>
            }
        },
        {
            "metadata_field": {
                <演算子>: <値>
            }
        }
    ]
}

データの更新

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
})