Skip to main content

RWA 大文件分域

Chroma 里没有和 Elasticsearch 一样的“分域”概念,但你可以通过元数据过滤(Metadata Filtering)来实现非常灵活的分域式查询。

简单来说,就是在向量相似性搜索的基础上,为数据附加标签(也就是“元数据”),用这些标签来限定查询的范围,从而实现“分域”的效果。

举个直观的例子:

  • 无过滤collection.query(query_texts=["AI"]) → 在整个集合里搜索关于 AI 的所有文档。
  • 加上“分域”过滤collection.query(query_texts=["AI"], where={"category": "science"}) → 只在 categoryscience 的“域”里搜索 AI 相关文档。

这样一来,你的“域”就是由数据结构化的元数据来定义的,并通过 where 参数来实现查询范围的限定。

🔎 如何实现“分域”查询?

Chroma 主要通过 wherewhere_document 这两个参数来细化查询。你可以把它们理解为在向量搜索前的一道预过滤筛子。

🧠 1. 基于元数据(Metadata)过滤

这是最核心的分域方式。通过 where 参数,你可以根据数据预定义的标签来筛选。

  • 精确匹配where={"status": "published"}
  • 范围查询where={"year": {"$gte": 2020}}
  • 集合操作where={"author": {"$in": ["张三", "李四"]}}
  • 逻辑组合:使用 $and / $or 组合多个条件。
    where={"$and": [{"year": {"$gte": 2020}}, {"category": "tech"}]}

✍️ 2. 基于文档内容(Document)过滤

如果你想在文档的文本内容中进行关键词匹配,可以使用 where_document 参数,这相当于内置的全文检索。

  • where_document={"$contains": "机器学习"}
  • where_document={"$regex": "RAG|LLM"}:你也可以使用更强大的正则表达式来匹配。

⚙️ 3. 控制查询返回的内容

通过 include 参数,你可以精确控制查询返回的字段。

collection.query(
query_texts=["向量数据库"],
where={"category": "tech"},
include=["documents", "metadatas", "distances"] # 返回文本、元数据和距离分数
)

这样能减少数据传输量,提升查询效率。

💻 实操:Python & TypeScript 代码示例

下面通过几种常见的场景,看看具体怎么用。

场景一:电商产品搜索

在一个电商平台的商品集合中,搜索“降噪耳机”,并限定价格区间和库存状态。

  • Python
    from chromadb import Search, K, Knn

    user_query = "降噪耳机"
    min_price, max_price = 50, 300

    combined_filter = (K("in_stock") == True) & (K("price") >= min_price) & (K("price") <= max_price)

    search = (Search()
    .where(combined_filter)
    .rank(Knn(query=user_query))
    .limit(20)
    .select(K.DOCUMENT, K.SCORE, "name", "price", "category"))

    results = collection.search(search)
  • TypeScript (类似 API)
    const results = await collection.search({
    where: {"category": "electronics", "price": {"$lte": 100}},
    rank: {$knn: {query: "wireless mouse"}},
    limit: 10
    });

场景二:RAG 应用中的知识库检索

在构建 RAG 应用时,需要从大量不同来源的文档里找到最相关的段落。这时可以通过元数据来限定搜索的文档源。

  • Python
    # 限定只从 2024 年的技术文档中搜索 RAG 相关内容
    results = collection.query(
    query_texts=["RAG implementation"],
    where={"doc_type": "tech_docs", "year": 2024}
    )
  • TypeScript
    const results = await collection.query({
    queryTexts: ["RAG implementation"],
    where: {"doc_type": "tech_docs", "year": 2024}
    });

🔧 进阶:让分域更高效

除了基础的过滤,Chroma 还提供了一些进阶功能,可以帮助你更好地管理和优化分域查询。

  • 使用 Schema 预定义索引:创建集合时,通过 Schema 预先为你的元数据字段(也就是“域”)指定索引类型,能显著提升查询性能。
  • 智能去重 (GroupBy):当一份大文档被切分成多个向量块时,使用 GroupBy 可以确保查询结果只返回最相关的那一块,避免结果被同一个长文档刷屏。这在相似度搜索中非常实用。
  • get() vs query():严格来说,get() 不计算向量相似度,主要用于精确的数据获取。但是,它同样支持 where 参数,所以你也可以用它来实现“分域”功能,只是不涉及向量排序。例如 collection.get(where={"status": "archived"})

通过这些过滤和高级功能,你完全可以在 Chroma 中模拟并实现类似“分域”的复杂检索逻辑。