JS调用Elasticsearch7.6查询多索引时报别名非法字符错误
问题根因
这个报错和Elasticsearch服务端无关,是@elastic/elasticsearch 7.6版本JS客户端的前置校验逻辑导致的,同一段查询能在Kibana正常执行就是最直接的证明:
- 你最初用逗号拼接字符串传
index1,index2的写法,会被客户端在发起请求前识别为单个索引/别名名称做合法性校验,逗号属于索引名明确禁止的特殊字符,直接触发报错,请求根本不会发送到ES服务端,自然走不到服务端的多索引拆分逻辑。 - 传数组格式依然报错,基本都是两个原因:
- 你贴的业务代码存在两处语法笔误,直接导致参数传递错乱:
- 调用
buildQuery构造参数时,queryIndex:${index1},${index2}``这行末尾错误使用分号结尾,对象字面量的属性之间必须用逗号分隔,写分号会导致JS解析参数对象失败,后续取值完全异常。 buildQuery的入参解构写错了:{ id. queryIndex }中把参数分隔符逗号写成了点,直接导致queryIndex变量取值为undefined,最终传给客户端的index参数是非法的undefined值,触发校验报错。
- 调用
- 用于拼接索引的
index1、index2变量存在非法值:7.6版本客户端不会自动过滤数组里的falsy值,如果两个变量中有undefined、null、空字符串、带前后空格或特殊字符的内容,会直接拼接进请求路径,触发非法字符校验。
- 你贴的业务代码存在两处语法笔误,直接导致参数传递错乱:
修复方法
针对7.6版本客户端,按以下步骤调整即可:
- 先修正代码里的语法笔误,多索引用数组格式传递,不要自行拼接逗号字符串:
const { client } = context; // graphql resolver传入的上下文 const query = buildQuery({ id: id, // 移除行尾错误的分号,直接传数组格式的多索引 queryIndex: [index1, index2] }); const results = await client.search(query); // 修正解构里的点为逗号 export const buildQuery = ({ id, queryIndex }) => ({ index: queryIndex, ignoreUnavailable: true, // 可选配置:避免查询时某一个索引不存在直接报错 body: { query: { bool: { must: [ { terms: { 'someId': [id] } } ] } }, aggs: { byindex: { terms: { field: '_index' }, aggs: { min_date: { min: { field: 'date', format: 'yyyy-MM-dd' } }, max_date: { max: { field: 'date', format: 'yyyy-MM-dd' } } } } } } });
- 修正后先打印确认传入的
index1、index2都是无多余空格、无特殊字符的合法字符串,不存在空值。 - 如果确认索引名完全合法依然触发客户端校验,可以在初始化ES客户端时关闭客户端侧的索引名前置校验,让请求正常发送到服务端处理即可,服务端本身对多索引的解析是正常的。如果不想改客户端配置,直接将JS客户端升级到7.10及以上版本即可,该版本已经修复了多指数组传参的校验bug。
内容的提问来源于stack exchange,提问作者bigalbunyan
相关产品推荐
相关产品推荐

