6. 检索查询
检索是 Chroma 最核心的功能。前面CRUD 部分已经做了一些介绍
6.1 基础语义检索
const results = await collection.query({
queryTexts: ['什么是量子纠缠?'], // 查询文本(自动向量化)
nResults: 3, // 返回最相似的3条
include: ['documents', 'metadatas', 'distances'],
})
// 结果结构
console.log(results.ids) // [['doc_001', 'doc_003', 'doc_002']] 注意是二维数组
console.log(results.documents) // [['量子纠缠是...', '波粒二象性...', '薛定谔的猫...']]
console.log(results.distances) // [[0.05, 0.18, 0.32]] 数值越小越相似(余弦距离)
console.log(results.metadatas) // [[{source:'...'}, ...]]
注意:results 都是二维数组,因为支持同时传多个查询(queryTexts 可以是数组)。
6.2 同时查询多个问题
const results = await collection.query({
queryTexts: [
'什么是量子纠缠?',
'薛定谔的猫说明了什么?',
],
nResults: 2,
})
// results.documents[0] → 第一个问题的检索结果
// results.documents[1] → 第二个问题的检索结果
6.3 用向量查询(自己传 embedding)
// 先把查询文本转成向量
const queryEmbedding = await getEmbeddings(['什么是量子纠缠?'])
const results = await collection.query({
queryEmbeddings: queryEmbedding, // 传向量而不是文本
nResults: 3,
include: ['documents', 'distances'],
})
6.4 理解相似度分数
// 余弦距离(hnsw:space = 'cosine'):
// 0.0 → 完全相同
// 0.0 ~ 0.3 → 高度相关
// 0.3 ~ 0.6 → 有一定关联
// 0.6 以上 → 基本不相关
results.distances[0].forEach((distance, i) => {
const similarity = 1 - distance // 转换为相似度(0~1,越高越好)
console.log(`结果${i+1}:相似度 ${similarity.toFixed(3)}`)
console.log(results.documents[0][i])
})
// 过滤低质量结果
const threshold = 0.6 // 距离阈值
const goodResults = results.documents[0].filter(
(_, i) => results.distances[0][i] < threshold
)
7. 元数据过滤
元数据过滤让你在语义检索的同时,加上精确的条件筛选。
7.1 基础过滤
// 只搜索来自特定文件的内容
const results = await collection.query({
queryTexts: ['退款流程'],
nResults: 5,
where: {
source: '退款政策.pdf', // 精确匹配
},
})
// 按数值过滤
const results2 = await collection.query({
queryTexts: ['量子力学基础'],
nResults: 5,
where: {
page: { $gte: 10 }, // page >= 10
},
})
7.2 支持的过滤操作符
// 比较操作符
where: { page: { $eq: 5 } } // 等于
where: { page: { $ne: 5 } } // 不等于
where: { page: { $gt: 5 } } // 大于
where: { page: { $gte: 5 } } // 大于等于
where: { page: { $lt: 10 } } // 小于
where: { page: { $lte: 10 } } // 小于等于
// 集合操作符
where: { source: { $in: ['文件A.pdf', '文件B.pdf'] } } // 在列表中
where: { source: { $nin: ['旧文件.pdf'] } } // 不在列表中
// 逻辑操作符
where: {
$and: [
{ chapter: '第一章' },
{ page: { $lte: 20 } },
]
}
where: {
$or: [
{ source: '文档A.pdf' },
{ source: '文档B.pdf' },
]
}
// 文本内容过滤(对 document 字段)
whereDocument: {
$contains: '量子', // 文档内容包含"量子"
}
whereDocument: {
$not_contains: '已废弃', // 文档内容不包含"已废弃"
}
7.3 实用场景示例
// 场景:多租户系统,每个用户只能查自己的数据
async function queryUserDocs(userId: string, question: string) {
return collection.query({
queryTexts: [question],
nResults: 5,
where: { userId }, // 只返回该用户的文档
})
}
// 场景:只查最新版本的文档
async function queryLatestDocs(question: string) {
return collection.query({
queryTexts: [question],
nResults: 5,
where: {
$and: [
{ version: { $eq: 'v2' } },
{ status: { $ne: '已下架' } },
],
},
})
}
// 场景:全文搜索(不需要向量,只按内容关键词过滤)
async function fullTextSearch(keyword: string) {
return collection.get({
whereDocument: { $contains: keyword },
include: ['documents', 'metadatas'],
})
}
💬 评论 0
还没有评论,快来抢沙发吧~