Elasticsearch向量库
在Elasticsearch(ES)最新版本(目前8.x系列)中,无需额外的“embedding插件”,因为ES从7.14版本开始就原生支持向量数据类型(dense_vector
) 和向量搜索能力,可直接作为向量库使用。其核心功能是存储、索引和搜索高维向量(如文本embedding、图像特征等),常用于语义搜索、推荐系统等场景。
一、核心概念与前提
- 向量(Vector):这里指高维浮点数组(如文本经BERT模型转换的768维embedding),用于量化表示数据的语义/特征。
dense_vector
类型:ES中用于存储向量的字段类型,支持高维向量(最大维度取决于版本,8.x支持至2048维)。- 向量搜索:通过计算向量间的相似度(如余弦相似度、欧氏距离),找到与目标向量最相似的结果(kNN搜索)。
二、作为向量库的使用步骤
1. 定义索引映射(Mapping)
首先创建一个包含dense_vector
字段的索引,用于存储向量数据。例如,存储“文本+embedding”的索引:
PUT /text_embeddings
{"mappings": {"properties": {"text": { "type": "text" }, // 原始文本"embedding": { // 向量字段"type": "dense_vector","dims": 768, // 向量维度(需与实际embedding维度一致,如BERT的768维)"index": true, // 开启索引(用于向量搜索)"similarity": "cosine" // 相似度计算方式(cosine/euclidean/l2_norm,默认l2_norm)}}}
}
dims
:必须与embedding的维度一致(如768、1024等)。similarity
:指定默认相似度算法(余弦相似度最常用于语义匹配)。index: true
:启用向量索引(基于HNSW算法的近似kNN搜索),提升搜索性能。
2. 插入带向量的数据
将文本通过embedding模型(如BERT、Sentence-BERT)转换为向量后,存入ES:
POST /text_embeddings/_doc/1
{"text": "Elasticsearch是一个分布式搜索引擎","embedding": [0.123, 0.456, ..., 0.789] // 768维向量(省略部分维度)
}POST /text_embeddings/_doc/2
{"text": "向量搜索用于语义匹配","embedding": [0.234, 0.567, ..., 0.890] // 另一768维向量
}
注意:向量需由外部模型生成(ES不负责文本→向量的转换),常见工具如Python的
sentence-transformers
库。
3. 执行向量搜索(kNN搜索)
给定一个查询文本,先通过相同的embedding模型转换为向量,再在ES中搜索最相似的向量:
GET /text_embeddings/_search
{"knn": {"field": "embedding", // 向量字段名"query_vector": [0.111, 0.222, ..., 0.333], // 查询文本的embedding向量"k": 3, // 返回最相似的3个结果"num_candidates": 100 // 候选集大小(影响精度和性能,建议为k的10-100倍)},"fields": ["text"] // 只返回原始文本字段
}
- 结果解释:ES会计算
query_vector
与索引中所有向量的相似度(按similarity
指定的算法),返回Top 3最相似的文档。 - 精确搜索:若需精确计算(非近似),可使用
script_score
结合向量函数(但性能较差,适合小数据量):
GET /text_embeddings/_search
{"query": {"script_score": {"query": { "match_all": {} },"script": {"source": "cosineSimilarity(params.query_vector, 'embedding') + 1.0","params": {"query_vector": [0.111, 0.222, ..., 0.333]}}}}
}
三、核心原理过程
1. 向量存储原理
dense_vector
字段将向量以浮点数组形式存储,与其他字段(如文本、数字)共同构成文档。- 当
index: true
时,ES会为向量构建近似最近邻(ANN)索引,基于HNSW(Hierarchical Navigable Small World)算法:- HNSW通过构建多层“导航图”,加速向量相似度计算,避免全量比对(全量比对在高维、大数据量下性能极差)。
- 索引过程中,向量会被插入到图中,每层保留部分邻居节点,查询时通过上层导航快速定位候选节点,再在下层精确筛选。
2. 向量搜索原理
- 查询向量生成:用户输入的查询文本(或其他数据)通过embedding模型转换为与存储向量同维度的向量。
- 近似匹配:ES使用HNSW索引,从查询向量出发,在导航图中快速找到
num_candidates
个候选向量(候选集)。 - 精确计算:对候选集中的向量,按指定的相似度算法(如余弦)计算精确得分。
- 结果返回:按得分排序,返回Top k个最相似的文档。
3. 与embedding模型的协同流程
完整的“文本语义搜索”流程如下:
原始文本 → (embedding模型)→ 向量 → 存入ES(dense_vector字段)↑ ↓
查询文本 → (同一embedding模型)→ 查询向量 → ES向量搜索 → 相似文本结果
- 关键:查询向量与存储向量必须来自同一embedding模型,否则向量空间不兼容,相似度无意义。
四、最新版本的优化(8.x)
- 更高维度支持:从早期版本的1024维提升至2048维,适配更大模型的embedding。
- 性能优化:HNSW索引的构建和查询效率提升,支持更大规模的向量数据(千万级以上)。
- 混合搜索:可同时结合向量搜索与传统文本搜索(如
match
查询),例如“语义相似且包含特定关键词”。
总结
ES最新版本通过dense_vector
字段和kNN搜索原生支持向量存储与检索,无需额外插件。其核心是利用HNSW算法实现高效的近似向量匹配,常与外部embedding模型结合,用于语义搜索等场景。使用时需注意向量维度一致性和相似度算法的选择,以保证搜索效果。