Elasticsearch k-NN搜索报错:期望[_doc]却得到[_knn_search] 求解决方案
解决Elasticsearch 7.10.2中k-NN搜索的
_knn_search错误 错误核心原因
Elasticsearch 7.10.2不支持knn_searchAPI,该API是Elasticsearch 8.0及以上版本才正式引入的。你使用的Python客户端es.knn_search()方法对应8.x版本的_knn_search端点,但7.10.2集群仅识别_doc相关端点,因此抛出类型不匹配错误。
解决方案:使用script_score实现k-NN搜索
在7.x版本中,需通过searchAPI结合script_score查询,用脚本计算向量间的相似度并排序。结合你索引映射中配置的l2_norm相似度,修改代码如下:
from elasticsearch import Elasticsearch from sentence_transformers import SentenceTransformer def search_function(query): es = Elasticsearch('http://3.110.155.4:9200/') model = SentenceTransformer("all-mpnet-base-v2") vector_of_input_keyword = model.encode(query).tolist() # 转换为列表适配ES脚本格式 # 构建基于script_score的k-NN查询 search_query = { "size": 10, # 对应原knn参数中的k值 "_source": ["id", "price", "bedroom", "bathroom", "sqft", "builtArea", "location_name"], "query": { "script_score": { "query": {"match_all": {}}, # 基础查询,可替换为业务过滤条件 "script": { "source": "1 / (1 + l2norm(params.query_vector, 'DescriptionVector'))", "params": { "query_vector": vector_of_input_keyword } } } } } res = es.search(index="house_6", body=search_query) return res["hits"]["hits"] input_query = input("Enter query to search: ") print("Search results:") print(search_function(input_query))
关键细节说明
- 脚本逻辑:
l2norm函数计算查询向量与文档向量的L2距离,通过1/(1+距离)将距离转换为0-1区间的分数(距离越小,分数越高),保证相似文档排在前列。 - size参数:替代原
knn配置中的k,控制返回的最相似条目数量。 - 向量格式:将模型输出的numpy数组转为Python列表,避免Elasticsearch无法解析numpy类型的问题。
额外优化建议
如果索引数据量较大,这种暴力计算方式性能会受限,可通过以下方式优化:
- 在
match_all位置添加业务过滤条件,缩小向量计算的文档范围 - 升级到Elasticsearch 8.x版本,使用官方提供的近似k-NN功能(性能更优)
内容的提问来源于stack exchange,提问作者SyedAbubakker Hahsmi
相关产品推荐
相关产品推荐

