有勇气的牛排博客

Elasticsearch8向量搜索|Python教程案例

有勇气的牛排 261 AI大模型 2025-04-19 22:35:13

1 前言

Elasticsearch 的 向量搜索(Vector Search) 是近年来为了支持语义搜索、推荐系统、图像搜索等 AI 场景而引入的重要功能。

1.1 什么是向量搜索?🧠

传统的关键字搜索匹配的是词语或短语,而 向量搜索(Vector Search) 匹配的是“语义相似性”。

举个例子:

用户搜索:如何提高网站性能?

  • 传统搜索:查找包含“提高"和”性能“的文档。
  • 向量搜索:找语义上与“网站优化”、“前端加速”、“服务器响应时间”相似的文章。

1.2 从哪个版本开始支持?🕰️

功能 支持版本 说明
dense_vector 字段 7.3+ 支持存储向量,但无法建立索引或排序,仅能作为过滤字段使用。
dense_vector 支持排序和脚本评分 7.5+ 可用 script_score 实现向量相似度排序(但效率较低)。
dense_vector + knn 支持向量索引(ANN) 8.0+ 正式支持原生 KNN 近似向量搜索(使用 HNSW 算法)。这是推荐使用的方式!
text_embedding 管道字段 8.11+ 内置支持向量生成(通过 Elastic Learned Sparse Encoder 模型)。

1.3 与其他工具对比

功能 Elasticsearch 8 FAISS Milvus Weaviate
原生搜索 + 向量索引 ❌(需外接 ES)
支持多字段查询
HNSW 向量搜索
自带嵌入模型(E5/ELSE) ✅(部分)

1.4 许可说明

Elasticsearch 的原生向量索引(index: true)功能属于 Elastic License,不是 Apache 2.0 免费许可。

如果你用的是 OpenSearch(ES 7.10 分支开源版本),其向量功能和支持程度也不同。

2 核心特性(以 Elasticsearch 8.x 为主)

2.1 dense_vector 字段类型

"content_vector": { "type": "dense_vector", "dims": 384, "index": true, "similarity": "cosine" }

dims:向量维度(必须与实际向量一致)。

index: true:开启 ANN 索引(必须)。

similarity:支持 cosine, dot_product, l2_norm

2.2 KNN 向量搜索(ANN 索引)

Elasticsearch 8.x 使用 HNSW(Hierarchical Navigable Small World)算法,允许高效的近似向量搜索(KNN)

"knn": { "field": "content_vector", "query_vector": [...], "k": 3, "num_candidates": 100 }

k: 返回最相似的前 k 条记录。

num_candidates: 从索引中选取的候选数量,越大越精确但慢。

2.3 支持模型推理(从 8.11 开始)

Elasticsearch 8.11+ 引入了内置的 text_embedding 管道处理器,允许你直接将文本变成向量(使用自带模型,无需 Python 推理):

{ "text_embedding": { "field_map": { "content": "content_vector" }, "model_id": ".elser_model_2" } }

3 dense_vector 案例

安装依赖

sentence-transformers==4.1.0 huggingface_hub[hf_xet] elasticsearch==8.13.0

3.1 创建索引

from elasticsearch import Elasticsearch es = Elasticsearch( "https://***.***.***.***:9200/", basic_auth=("elastic", "***"), verify_certs=False ) index_name = "my_blog_article" # 删除旧索引(如存在) if es.indices.exists(index=index_name): es.indices.delete(index=index_name) # 创建索引映射 mapping = { "mappings": { "properties": { "title": {"type": "text"}, "content": {"type": "text"}, "content_vector": { "type": "dense_vector", "dims": 512, # 向量维度,取决于你的模型 "index": True, "similarity": "cosine" } } } } es.indices.create(index=index_name, body=mapping)

3.2 插入博客文章(文本 + 向量)

from sentence_transformers import SentenceTransformer from elasticsearch import Elasticsearch es = Elasticsearch( "https://***.***.***.***:9200/", basic_auth=("elastic", "***"), verify_certs=False ) # 输出512维向量 model = SentenceTransformer("BAAI/bge-small-zh-v1.5") # 示例博客文章 articles = [ {"title": "Elasticsearch 简介", "content": "Elasticsearch 是一个基于 Lucene 的搜索引擎,适用于全文检索。"}, {"title": "机器学习基础", "content": "本文介绍了机器学习中的监督学习和非监督学习方法。"}, {"title": "如何使用 Python 操作 Elasticsearch", "content": "作者:有勇气的牛排, 通过 Python 的 elasticsearch 库,可以方便地查询和插入数据。"} ] index_name = "my_blog_article" # 插入数据 for i, article in enumerate(articles): vector = model.encode(article["content"]).tolist() print(article) print(vector) doc = { "title": article["title"], "content": article["content"], "content_vector": vector } es.index(index=index_name, id=i + 1, document=doc)

elasticsearch插入向量数据

3.3 向量查询相似博客

from sentence_transformers import SentenceTransformer from elasticsearch import Elasticsearch es = Elasticsearch( "https://***.***.***.***:9200/", basic_auth=("elastic", "***"), verify_certs=False ) index_name = "my_blog_article" # 输出512维向量 model = SentenceTransformer("BAAI/bge-small-zh-v1.5") # query_text = "如何用 Python 查询 Elasticsearch" query_text = "有勇气的牛排" query_vector = model.encode(query_text).tolist() # 使用 knn 查询(Elasticsearch 8+ 支持) query_body = { "knn": { "field": "content_vector", "query_vector": query_vector, "k": 2, "num_candidates": 10 }, "_source": ["title", "content"] } response = es.search(index=index_name, body=query_body) for hit in response["hits"]["hits"]: print(f"得分: {hit['_score']:.4f}") print(f"标题: {hit['_source']['title']}") print(f"内容: {hit['_source']['content']}\n")

输出

得分: 0.8303 标题: 如何使用 Python 操作 Elasticsearch 内容: 作者有勇气的牛排, 通过 Python 的 elasticsearch 库,可以方便地查询和插入数据。 得分: 0.6260 标题: Elasticsearch 简介 内容: Elasticsearch 是一个基于 Lucene 的搜索引擎,适用于全文检索。

Elasticsearch向量化搜索


留言

专栏
文章
加入群聊