chroma db 向量数据库 使用指南(二)
使用指南
选择语言
- Python
- JavaScript
启动 Chroma 客户端
import chromadb
默认情况下,Chroma 使用内存数据库,该数据库在退出时持久化并在启动时加载(如果存在)。这适用于受机器内存限制的许多实验/原型设计工作负载。
from chromadb.config import Settings
client = chromadb.Client(Settings(
chroma_db_impl="duckdb+parquet",
persist_directory="/path/to/persist/directory" # Optional, defaults to .chromadb/ in the current directory
))
这
persist_directory
是 Chroma 将其数据库文件存储在磁盘上并在启动时加载它们的地方。
木星笔记本
在普通的 python 程序中,
.persist()
如果您设置它,它将自动发生。但在 Jupyter Notebook 中,您需要
手动
调用
client.persist()
.
客户端对象有一些有用的便捷方法。
client.heartbeat() # returns a nanosecond heartbeat. Useful for making sure the client remains connected.
client.reset() # Empties and completely resets the database. ⚠️ This is destructive and not reversible.
以客户端/服务器 模式
Chroma 还可以配置为使用磁盘上的数据库,这对于无法放入内存的较大数据很有用。要在客户端服务器模式下运行 Chroma,请运行 docker 容器:
docker-compose up -d --build
然后更新您的色度客户端以指向 docker 容器。默认:
localhost:8000
import chromadb
from chromadb.config import Settings
chroma_client = chromadb.Client(Settings(chroma_api_impl="rest",
chroma_server_host="localhost",
chroma_server_http_port="8000"
))
就是这样!
client-server
Chroma 的 API 将以仅此更改的模式运行。
使用 集合
Chroma 允许您使用原语管理嵌入集合
collection
。
创建、检查和删除 集合
Chroma 在 url 中使用集合名称,因此命名它们有一些限制:
- 名称的长度必须介于 3 到 63 个字符之间。
- 名称必须以小写字母或数字开头和结尾,中间可以包含点、破折号和下划线。
- 名称不得包含两个连续的点。
- 该名称不能是有效的 IP 地址。
Chroma 集合是使用名称和可选的嵌入函数创建的。如果您提供嵌入函数,则必须在每次获取集合时提供它。
collection = client.create_collection(name="my_collection", embedding_function=emb_fn)
collection = client.get_collection(name="my_collection", embedding_function=emb_fn)
警告
如果您以后希望这样做
get_collection
,则必须使用您在创建集合时提供的嵌入函数来这样做
嵌入函数以文本为输入,进行标记化和嵌入。如果没有提供嵌入函数,Chroma 将默认使用
句子变换器。
您可以了解有关 嵌入函数的 更多信息,以及如何创建您自己的嵌入函数。
可以使用 检索现有集合
.get_collection
,使用 删除现有集合
.delete_collection
。如果集合存在,您也可以使用
.get_or_create_collection
它来获取它,如果不存在,则创建它。
collection = client.get_collection(name="test") # Get a collection object from an existing collection, by name. Will raise an exception if it's not found.
collection = client.get_or_create_collection(name="test") # Get a collection object from an existing collection, by name. If it doesn't exist, create it.
client.delete_collection(name="my_collection") # Delete a collection and all associated embeddings, documents, and metadata. ⚠️ This is destructive and not reversible
集合有一些有用的便捷方法。
collection.peek() # returns a list of the first 10 items in the collection
collection.count() # returns the number of items in the collection
collection.modify(name="new_name") # Rename the collection
改变距离 函数
create_collection
还带有一个可选
metadata
参数,可用于通过设置值来自定义嵌入空间的距离方法
hnsw:space
collection = client.create_collection(
name="collection_name",
metadata={"hnsw:space": "cosine"}
)
的有效选项
hnsw:space
是“l2”、“ip”或“cosine”。
可以在此处
的 Hnswlib 文档中找到每个方程式。
向 集合
将数据添加到 Chroma 中
.add
。
原始文件:
collection.add(
documents=["lorem ipsum...", "doc2", "doc3", ...],
metadatas=[{"chapter": "3", "verse": "16"}, {"chapter": "3", "verse": "5"}, {"chapter": "29", "verse": "11"}, ...],
ids=["id1", "id2", "id3", ...]
)
如果 Chroma 传递了一个列表
documents
,它将自动标记化并将它们嵌入到集合的嵌入函数中(如果在创建集合时没有提供,则将使用默认值)。Chroma 也会存储它们
documents
自己。如果文档太大而无法使用所选的嵌入函数进行嵌入,则会引发异常。
每个文档必须有一个唯一的关联
id
。Chroma 不会为您跟踪 ID 的唯一性,由调用者决定是否添加相同的 ID 两次。
metadata
可以为每个文档提供可选的字典列表,以存储附加信息并启用过滤。
或者,您可以直接提供文档关联列表
embeddings
,Chroma 将存储关联文档而不嵌入它们本身。
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", ...]
)
如果提供的
embeddings
维度与集合不同,则会引发异常。
您还可以将文档存储在别处,只需向 Chroma 提供一个列表
embeddings
即可
metadata
。您可以使用 将
ids
嵌入与存储在别处的文档相关联。
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", ...]
)
查询 集合
可以使用 方法以多种方式查询色度集合
.query
。
您可以通过一组查询
query_embeddings
。
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"}
)
查询将按顺序返回
n_results
与每个最接近的匹配项。
query_embedding
可以提供一个可选的
where
过滤器字典,以通过与每个文档相关联的方式过滤结果
metadata
。此外,
where_document
可以提供一个可选的过滤器字典来按文档的内容过滤结果。
如果提供的
query_embeddings
维度与集合不同,则会引发异常。
您还可以通过一组查询
query_texts
。Chroma 将首先使用
query_text
集合的嵌入函数对每个进行嵌入,然后使用生成的嵌入执行查询。
collection.query(
query_texts=["doc10", "thus spake zarathustra", ...]
n_results=10,
where={"metadata_field": "is_equal_to_this"},
where_document={"$contains":"search_string"}
)
您还可以
id
使用
.get
.
collection.get(
ids=["id1", "id2", "id3", ...],
where={"style": "style1"}
)
.get
还支持
where
和
where_document
过滤器。如果没有
ids
提供,它将返回集合中与
where
和
where_document
过滤器匹配的所有项目。
选择 返回
使用 get 或 query 时,您可以使用 include 参数指定要返回的数据 -
embeddings
、
documents
、
metadatas
和 query 中的任何一个
distances
。默认情况下,Chroma 将返回
documents
,
metadatas
在查询的情况下,返回
distances
结果的 。
embeddings
默认情况下被排除在性能之外并且
ids
总是被返回。您可以通过将包含字段名称的数组传递给查询或 get 方法的 includes 参数来指定要返回哪些。
# Only get documents and ids
collection.get(
include=["documents"]
)
collection.query(
query_embeddings=[[11.1, 12.1, 13.1],[1.1, 2.3, 3.2] ...],
include=["documents"]
)
使用 Where 过滤器
metadata
Chroma 支持按内容过滤查询
document
。filter
where
用于按 过滤
metadata
,
where_document
filter 用于按
document
内容过滤。
按 元数据
为了过滤元数据,您必须
where
为查询提供过滤字典。字典必须具有以下结构:
{
"metadata_field": {
<Operator>: <Value>
}
}
过滤元数据支持以下运算符:
-
$eq
- 等于(字符串,整数,浮点数) -
$ne
- 不等于(字符串、整数、浮点数) -
$gt
- 大于(整数,浮点数) -
$gte
- 大于或等于(整数,浮点数) -
$lt
- 小于(整数,浮点数) -
$lte
- 小于或等于(整数,浮点数)
使用 $eq 运算符等同于使用
where
过滤器。
{
"metadata_field": "search_string"
}
# is equivalent to
{
"metadata_field": {
"$eq": "search_string"
}
}
按文档 内容
为了过滤文档内容,您必须
where_document
为查询提供过滤字典。字典必须具有以下结构:
# Filtering for a search_string
{
"$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>
}
}
]
}
更新
集合
集合中项目的任何属性都可以使用
.update
.
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", ...],
)
如果
id
在集合中找不到 an,将引发异常。如果
documents
提供时没有相应的
embeddings
,嵌入将使用集合的嵌入函数重新计算。
如果提供的
embeddings
维度与集合不同,则会引发异常。
Chroma 还支持
upsert
更新现有项目或添加它们(如果它们尚不存在)的操作。
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", ...],
)
如果 an
id
不存在于集合中,则将根据创建相应的项目
add
。具有现有
id
s 的项目将根据 更新
update
。
从 集合
Chroma 支持
id
使用
.delete
. 与每个项目关联的嵌入、文档和元数据将被删除。⚠️当然,这是破坏性操作,无法撤销。
collection.delete(
ids=["id1", "id2", "id3",...],
where={"chapter": "20"}
)
.delete
还支持
where
过滤器。如果没有
ids
提供,它将删除集合中与
where
过滤器匹配的所有项目。