注意,get 用于按条件直接读取集合内的原始数据记录,属于元数据 / ID / 文本过滤查询,不是向量相似度检索。
方法签名如下:
collection.get(
ids=None, # 只取这几个 id
where=None, # 元数据过滤
limit=None, # 最多返回多少条
offset=None, # 跳过多少条
where_document=None, # 文档内容过滤
include=["metadatas", "documents"], # 要返回哪些字段
)参数说明:
ids:类型为 list[str] | None,用来指定文档 ID 列表,get 仅返回列表内存在的 ID 对应的记录。例如:ids=["id001","id002"]
where:类型为 dict | None,用来基于 metadata 元数据的筛选过滤器,支持$eq、$ne、$gt、$gte、$lt、$lte、$in、$nin、$and、$or 操作符。例如:where={"category":"临时"}
limit:类型为 int | None,用来限制本次查询最多返回的记录条数。传递 None 代表不限制条数,返回所有匹配结果。
offset:类型为 int | None,指定查询时跳过前面 N 条数据,用于分页。从第 offset 条之后开始取数据,默认 0。
where_document:类型为 dict | None,基于 document 文档原文过滤,仅支持 $contains(文本包含子串)。例如:where_document={"$contains":"测试"} 查询 document 包含“测试”字符串的记录。
include:类型为 list[str],用来指定返回结果里携带哪些字段,可选值如下:
"documents":文档文本
"metadatas":元数据
"embeddings":向量(会占用大量内存,按需开启)
"uris":资源链接
注意了,get 方法返回的数据和传统数据库查询按行返回完全不同,它是按列返回的,格式如下:
{
"ids": [],
"documents": [],
"metadatas": [],
"embeddings": [], # 仅include包含embeddings才存在
"uris": [] # 仅include包含uris才存在
}上面介绍了 get 方法的语法,下面将通过示例来演示 get 的用法。
当我们调用 get 时,不传递任何参数,将返回所有数据。不推荐这么去做,如果集合数据非常多,内存吃不消的。
例如:
import chromadb
client = chromadb.EphemeralClient()
collection = client.get_or_create_collection("demo_collection", embedding_function=None)
# 先灌几条数据,后面的查询 / 过滤才看得到东西
collection.add(
ids=["r1", "r2", "r3", "r4", "r5"],
documents=[
"退款流程:在订单页点申请退款,3 个工作日内到账",
"发票开具:在订单详情页申请电子发票",
"物流查询:发货后可在物流详情里看到进度",
"退货政策:7 天无理由退货,运费买家承担",
"账号安全:如何修改密码和绑定手机",
],
metadatas=[
{"cat": "售后", "year": 2024, "score": 0.9, "tags": ["退款"]},
{"cat": "财务", "year": 2023, "score": 0.5, "tags": ["发票"]},
{"cat": "物流", "year": 2024, "score": 0.7, "tags": ["物流"]},
{"cat": "售后", "year": 2022, "score": 0.3, "tags": ["退货"]},
{"cat": "账号", "year": 2024, "score": 0.6, "tags": ["安全"]},
],
)
result = collection.get(
ids=None, # 只取这几个 id
where=None, # 元数据过滤
limit=None, # 最多返回多少条
offset=None, # 跳过多少条
where_document=None, # 文档内容过滤
include=["metadatas", "documents"], # 要返回哪些字段
)
print(f"ids={result["ids"]}")
print(f"documents={result["documents"]}")
print(f"metadatas={result["metadatas"]}")运行示例,输出如下:
ids=['r1', 'r2', 'r3', 'r4', 'r5']
documents=['退款流程:在订单页点申请退款,3 个工作日内到账',
'发票开具:在订单详情页申请电子发票', '物流查询:发货后可在物流详情里看到进度',
'退货政策:7 天无理由退货,运费买家承担', '账号安全:如何修改密码和绑定手机']
metadatas=[{'year': 2024, 'cat': '售后', 'tags': ['退款'], 'score': 0.9},
{'cat': '财务', 'score': 0.5, 'year': 2023, 'tags': ['发票']},
{'cat': '物流', 'year': 2024, 'score': 0.7, 'tags': ['物流']},
{'tags': ['退货'], 'cat': '售后', 'score': 0.3, 'year': 2022},
{'year': 2024, 'cat': '账号', 'score': 0.6, 'tags': ['安全']}]从输出可知,将整个集合数据全部输出了,如果我们要输出整个集合数据,建议显示通过 limit + offset 分页获取,不要一次性全部取出 —— 数据量大时会很慢。
还需要注意,如果你查询数据,不需要返回 embeddings,就不要让他返回,数据太大了,影响查询效率。
和删除的 ids 一样,用来明确获取指定 ID 的数据,非常简单,用法如下:
res = col.get(ids=["d1", "d3"])执行代码,将返回 id 为 d1、d3 的记录信息。
分页很重要,特别对于查询数据量巨大的集合。如果查询条件很简单,一次可能会返回成千上万条数据,这太影响效率了,常用做法是分页,每次一页返回 20 条、100 条,查询效率更快。
用法如下:
# 从位置0开始,查询100条记录
page1 = col.get(limit=100, offset=0) # 如果页大小为100,这是第一页
# 从位置100开始,查询100条记录
page2 = col.get(limit=100, offset=100) # 如果页大小为100,这是第二页示例:
import chromadb
client = chromadb.EphemeralClient()
collection = client.get_or_create_collection("demo_collection", embedding_function=None)
# 先灌几条数据,后面的查询 / 过滤才看得到东西
collection.add(
ids=["r1", "r2", "r3", "r4", "r5"],
documents=[
"退款流程:在订单页点申请退款,3 个工作日内到账",
"发票开具:在订单详情页申请电子发票",
"物流查询:发货后可在物流详情里看到进度",
"退货政策:7 天无理由退货,运费买家承担",
"账号安全:如何修改密码和绑定手机",
],
metadatas=[
{"cat": "售后", "year": 2024, "score": 0.9, "tags": ["退款"]},
{"cat": "财务", "year": 2023, "score": 0.5, "tags": ["发票"]},
{"cat": "物流", "year": 2024, "score": 0.7, "tags": ["物流"]},
{"cat": "售后", "year": 2022, "score": 0.3, "tags": ["退货"]},
{"cat": "账号", "year": 2024, "score": 0.6, "tags": ["安全"]},
],
)
result = collection.get(offset=1, limit=2)
print(f"ids={result["ids"]}") # ids=['r2', 'r3']
result = collection.get(offset=3, limit=2)
print(f"ids={result["ids"]}") # ids=['r4', 'r5']注意:offset 大的时候性能会下降,因为服务端要扫过前面那些。真要导全量数据,更好的办法是按某个 metadata 字段分片(比如按 doc_id 分批取)。
include 可选的值:
| 值 | 含义 |
| "documents" | 原始文本 |
| "embeddings" | 向量(大,默认不带) |
| "metadatas" | 元数据 |
| "uris" | 数据地址 |
| "data" | 按 uri 加载回来的数据(需要集合配了 data_loader) |
| "distances" | 只在 query 里有效 |
get 不传 include 时默认是 ["metadatas", "documents"],不带向量。想拿向量必须显式说,就像这样:
col.get(ids=["a1"], include=["embeddings"])传入 include 会覆盖默认值,不是追加。想全都要就写全:
col.get(ids=["a1"], include=["documents", "metadatas", "embeddings", "uris"])include=["data"] 需要集合配了 data_loader,否则:
ValueError: You must set a data loader on the collection if loading from URIs.例如:使用 OpenCLIPEmbeddingFunction 嵌入函数计算图片向量,ImageLoader 用于加载图片数据。
import chromadb
from chromadb.utils.data_loaders import ImageLoader
from chromadb.utils.embedding_functions import OpenCLIPEmbeddingFunction
# 创建集合时指定 data_loader
loader = ImageLoader()
# 图片嵌入函数
ef = OpenCLIPEmbeddingFunction()
client = chromadb.EphemeralClient()
collection = client.get_or_create_collection(
name = "demo_collection",
embedding_function = ef,
data_loader = loader
)
# 先灌几条数据,后面的查询 / 过滤才看得到东西
collection.add(
ids=["r1",],
metadatas=[
{"cat": "售后", "year": 2024, "score": 0.9, "tags": ["退款"]},
],
uris = [
"../../images/apple1.jpg"
]
)
result = collection.get(ids=["r1"], include=["data"])
print(result)运行示例,输出如下:
{'ids': ['r1'], 'embeddings': None, 'documents': None,
'uris': ['../../images/apple1.jpg'], 'included': ['data', 'uris'],
'data': [array([[
[[253, 253, 253],
[253, 253, 253],
[254, 254, 254],
...,
[255, 255, 255],
[255, 255, 255],
[255, 255, 255]]], shape=(118, 138, 3), dtype=uint8)], 'metadatas': [{'year': 2024, 'cat': '售后', 'tags': ['退款'], 'score': 0.9}]}
ids=['r1']注意,为了正确运行上面代码,需要安装如下依赖:
pip install open-clip-torch pillow torch torchvision