Chroma查询集合:从基础检索到高级过滤的完整指南

Chroma查询集合:从基础检索到高级过滤的完整指南

当你成功地将数据存入Chroma集合后,下一步自然是如何高效、精准地查询这些数据。Chroma提供了两套核心的查询API:相似性搜索(Query)直接获取(Get) 。结合强大的元数据过滤全文搜索功能,你可以构建从简单到复杂的各种检索逻辑。本文将基于官方文档,为你全面解析Chroma的查询艺术。

1. 核心查询:相似性搜索(Query)

query 方法是Chroma的核心功能,它执行近似最近邻(ANN)搜索,找到与你的输入最相似的向量。

1.1 基础相似性搜索

最常用的方式是传入文本,Chroma会自动使用集合的嵌入函数将其转换为向量进行搜索。

python

python 复制代码
import chromadb
# 假设你已经有了一个client和collection
# client = chromadb.Client()
# collection = client.get_collection("my_docs")

results = collection.query(
    query_texts=["机器学习的应用", "深度学习的原理"],  # 可以传入多个查询
    n_results=5  # 返回每个查询最相似的5个结果
)

参数说明

  • query_texts:一个文本列表,Chroma会自动嵌入它们。

  • query_embeddings:如果你已经有向量,可以直接传入。当集合没有嵌入函数时,这是必需的。向量的维度必须与集合中的一致。

  • n_results:每个查询返回的结果数量,默认为10。

  • ids:可选,如果提供,搜索将仅限定在这些ID的记录范围内。

1.2 控制返回内容

默认情况下,query 返回 documentsmetadatasdistances。你可以使用 include 参数精确控制返回的数据。

python

python 复制代码
results = collection.query(
    query_texts=["人工智能"],
    include=["documents", "metadatas", "embeddings", "distances"]  # 返回所有字段
)

1.3 查询结果的结构

query 返回的结果是**按列组织(column-major)**的,并且每组查询的结果是分开的。一个典型的返回结构如下:

json

python 复制代码
{
  "ids": [["doc_1", "doc_7"]],  // 外层列表对应每个查询,内层列表是结果ID
  "embeddings": [[[1, 2, 3, 4], [1, 2, 3, 4]]], // 对应每个结果的向量
  "documents": [["Chroma stores vectors.", "Embeddings power semantic search."]],
  "metadatas": [[
    {"source": "docs", "topic": "intro"},
    {"source": "blog", "topic": "search"}
  ]],
  "distances": [[0.12, 0.21]],  // 距离值,越小越相似
  "included": ["embeddings", "documents", "metadatas", "distances"]
}

遍历结果的小技巧

python

python 复制代码
results = collection.query(query_texts=["第一个查询", "第二个查询"])
# 外层循环:遍历每个查询的结果集
for ids_list, docs_list, metas_list in zip(results["ids"], results["documents"], results["metadatas"]):
    # 内层循环:遍历一个查询返回的多个结果
    for id, doc, meta in zip(ids_list, docs_list, metas_list):
        print(f"ID: {id}, Doc: {doc}, Meta: {meta}")

2. 精确获取:Get 方法

当你不需要相似性排序 ,只想根据条件精确获取记录时,应该使用 get 方法。

python

python 复制代码
# 根据ID获取
records_by_id = collection.get(ids=["doc1", "doc3"])

# 分页获取所有记录
all_records = collection.get(limit=50, offset=0)

# 只返回文档和元数据
records = collection.get(include=["documents", "metadatas"])

get 返回的数据结构是扁平化的,每个数组中的元素一一对应同一条记录。

json

python 复制代码
{
  "ids": ["doc_1", "doc_7"],
  "embeddings": [[1, 2, 3, 4], [1, 2, 3, 4]],
  "documents": ["Chroma stores vectors.", "Embeddings power semantic search."],
  "metadatas": [{"source": "docs"}, {"source": "blog"}],
  "included": ["documents", "metadatas"]
}

3. 精准过滤:元数据过滤(where)

元数据过滤是让检索结果更精准的关键。通过在 queryget 中使用 where 参数,你可以根据与每条记录关联的元数据进行筛选。

3.1 基础比较操作符

Chroma支持多种比较操作符:$eq(等于,可省略)、$ne(不等于)、$gt(大于)、$gte(大于等于)、$lt(小于)、$lte(小于等于)。

python

python 复制代码
# 筛选 page 等于 10 的记录(两种写法等价)
collection.get(where={"page": 10})
collection.get(where={"page": {"$eq": 10}})

# 筛选 page 大于 5 且小于等于 20 的记录
collection.get(where={"page": {"$gt": 5, "$lte": 20}})

3.2 包含操作符:in 和 nin

检查元数据字段的值是否在一个列表中。

python

python 复制代码
# 获取作者是 Rowling, Fitzgerald 或 Herbert 的记录
collection.get(
    where={"author": {"$in": ["Rowling", "Fitzgerald", "Herbert"]}}
)

# 获取作者不是上述三人的记录(或没有author字段的记录)
collection.get(
    where={"author": {"$nin": ["Rowling", "Fitzgerald", "Herbert"]}}
)

3.3 数组元数据的过滤:contains 和 not_contains

如果你在元数据中存储了数组(例如标签列表),可以使用这两个操作符进行过滤。

python

python 复制代码
# 假设我们添加了带有数组元数据的记录
collection.add(
    ids=["movie1", "movie2", "movie3"],
    documents=["...", "...", "..."],
    metadatas=[
        {"genres": ["action", "comedy"], "year": 2020},
        {"genres": ["drama"], "year": 2021},
        {"genres": ["action", "thriller"], "year": 2022},
    ],
)

# 查询所有包含 "action" 标签的记录
action_movies = collection.get(
    where={"genres": {"$contains": "action"}}
)

# 查询所有不包含 "comedy" 标签的记录
non_comedy = collection.get(
    where={"genres": {"$not_contains": "comedy"}}
)

# 结合其他条件:2021年后上映的动作片
filtered = collection.get(
    where={
        "$and": [
            {"genres": {"$contains": "action"}},
            {"year": {"$gte": 2021}}
        ]
    }
)

数组过滤的约束

  • 数组元素类型必须一致(如全是字符串)。

  • $contains 的值必须是标量,且类型与数组元素一致。

  • 空数组和嵌套数组是不允许的。

3.4 逻辑组合:and 和 or

你可以使用逻辑操作符将多个条件组合起来,构建复杂的过滤逻辑。

  • $and:满足所有条件。

    python

    python 复制代码
    # 筛选 page 在 5 到 10 之间的记录
    collection.get(where={
        "$and": [
            {"page": {"$gte": 5}},
            {"page": {"$lte": 10}}
        ]
    })
  • $or:满足任一条件。

    python

    python 复制代码
    # 筛选颜色为红色或蓝色的记录
    collection.get(where={
        "$or": [
            {"color": "red"},
            {"color": "blue"}
        ]
    })

4. 内容检索:全文搜索(where_document)

有时你需要根据文档的文本内容 进行过滤,而不是语义向量。这时可以使用 where_document 参数。它支持两种操作符:$contains/$not_contains$regex/$not_regex

4.1 关键词包含搜索

$contains 用于检查文档是否包含特定的关键词。注意:这是大小写敏感的。

python

python 复制代码
# 获取所有文档中包含 "Chroma" 关键词的记录
results = collection.get(
    where_document={"$contains": "Chroma"}
)

# 在相似性搜索中同时应用全文过滤
query_results = collection.query(
    query_texts=["向量数据库"],
    where_document={"$contains": "Chroma"}
)

4.2 正则表达式搜索

当需要更复杂的模式匹配时,可以使用 $regex

python

python 复制代码
# 查找文档中看起来像电子邮件地址的记录
email_pattern = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
results = collection.get(
    where_document={"$regex": email_pattern}
)

4.3 逻辑组合在全文搜索中的应用

where_document 同样支持 $and$or 来组合多个搜索条件。

python

python 复制代码
# 文档中必须同时包含 "machine" 和 "learning"
results = collection.get(
    where_document={
        "$and": [
            {"$contains": "machine"},
            {"$contains": "learning"}
        ]
    }
)

# 文档中包含 "hello" 或 "world"
results = collection.get(
    where_document={
        "$or": [
            {"$contains": "hello"},
            {"$contains": "world"}
        ]
    }
)

5. 组合查询:元数据过滤 + 全文搜索

Chroma 最强大的地方在于,你可以将 where(元数据过滤)和 where_document(全文搜索)结合使用,与 queryget 一起,实现高度精准的检索。

python

python 复制代码
# 场景:查找 2021 年之后发布,文档内容包含 "Chroma",且与 "机器学习" 语义最相似的文档
advanced_results = collection.query(
    query_texts=["机器学习"],
    n_results=10,
    where={"year": {"$gte": 2021}},  # 元数据条件
    where_document={"$contains": "Chroma"}  # 全文搜索条件
)

# 同样适用于 get 操作
specific_records = collection.get(
    where={"author": "John"},
    where_document={"$regex": ".*重要结论.*"},
    limit=5
)

总结

通过本文,你已经掌握了Chroma查询集合的完整工具箱:

  1. 基础查询 :用 query 进行语义搜索,用 get 进行精确获取。

  2. 元数据过滤 :利用 where 和各种操作符($eq, $gt, $in, $contains 等)对记录的标签、属性进行筛选,并可通过 $and/$or 构建复杂逻辑。

  3. 全文搜索 :利用 where_document 对文档内容进行关键词包含或正则表达式匹配。

  4. 组合使用:将上述功能结合,实现既考虑语义相似度,又满足特定元数据和内容条件的"上帝视角"式检索。

熟练运用这些查询技巧,你将能充分挖掘Chroma集合中数据的价值,为上层应用提供精准、高效的信息支持。开始在你的RAG系统或语义搜索应用中实践吧!

相关推荐
阿杰真不会敲代码3 小时前
Elasticsearch 入门到实战:安装 + CRUD + 查询
java·大数据·elasticsearch·搜索引擎
曾阿伦15 小时前
Elasticsearch 自定义分词匹配与同义词处理实战详解
大数据·elasticsearch·搜索引擎
YDS82917 小时前
SpringCloud —— Elasticsearch的DSL查询
java·elasticsearch·搜索引擎·spring cloud
沪漂阿龙18 小时前
语义搜索与RAG:让搜索引擎真正理解你的意图,让AI告别“幻觉”
人工智能·搜索引擎
LaughingZhu19 小时前
Product Hunt 每日热榜 | 2026-03-12
大数据·数据库·人工智能·经验分享·搜索引擎
白宇横流学长1 天前
Elasticsearch集群搭建
大数据·elasticsearch·搜索引擎
MarsLord1 天前
ElasticSearch快速入门实战(3)-集群、分片、同步MySQL数据
大数据·elasticsearch·搜索引擎
Elastic 中国社区官方博客1 天前
需要知道某个同义词是否实际匹配了你的 Elasticsearch 查询吗?
大数据·数据库·elasticsearch·搜索引擎·全文检索
初次攀爬者2 天前
Elasticsearch 脑裂问题详解与新旧版本解决方案
elasticsearch·搜索引擎