找回密码
 立即注册
首页 业界区 业界 ES查询优化随记1: 多路向量查询 & KNN IO排查 & 高效Fil ...

ES查询优化随记1: 多路向量查询 & KNN IO排查 & 高效Filter使用

马璞玉 2025-6-3 00:02:04
哈哈最近感觉自己不像算法倒像是DB,整天围着ES打转,今天查IO,明天查内存,一会优化查询,一会优化吞吐。毕竟RAG离不开知识库,我们的选型是ES,于是这一年都是和ES的各种纠葛。所以顺手把近期获得的一些小tips记下来,万一有人和我踩进了一样的坑,也能早日爬出来。当前使用的ES版本是8.13,和7版本有较大的差异,用7.X的朋友这一章可能有不适配。本章主要覆盖以下


  • 多Query向量查询的各种方案:Script,Knn(mesearch)
  • KNN查询IOUtil过高问题排查
  • 如何使用Filter查询更高效
多Query向量查询的各种方法

大模型的知识库都离不开向量查询,并且当前的RAG往往会对用户query进行多角度的改写和发散,因此会涉及多query同时进行向量查询。如果用ES实现的话,常用的有以下几种形式

  • 多向量Pooling Script查询:多个query的向量平均后进行查询,查询效果不好,因为Pooling往往会损失很多信息,虽然把多个向量压缩成了一个向量,查询效率更高压力更小,但是效果差的离谱。但是对使用ES 7.X版本的朋友可能也是一种选择。
  1. query_body = {
  2.     "size":10
  3.     "query": {
  4.             "bool": {
  5.                 "must": [{
  6.                     "script_score": {
  7.                         "query": {"match_all": {}},  
  8.                         "script": {
  9.                             "source": f"cosineSimilarity(params.query_vector, 'vectors')",
  10.                             "params": {"query_vector": avg_embedding}
  11.                         }
  12.                     }
  13.                 }]
  14.             }
  15.         }
  16. }
复制代码

  • 向量script循环取cosine的最大值或者平均值:使用ES 7且的朋友一般的选项,因为7的版本里部分没有KNN的支持,因此只能使用script线性遍历向量。而不把所有向量召回的内容都取回来进行重排序主要是IO的考虑,返回的条数更少传输压力更小。以下为python的查询示例,embedding_list是多query的向量数组。
[code]query_body = {    "query": {        "function_score": {            "script_score": {                "script": {                    "source": """                        double max_score = -1.0;                        if (doc[params.field].size() == 0) return 0; // 空值保护                        for (int i=0; i
您需要登录后才可以回帖 登录 | 立即注册