ES 7.14开启Profile API后响应无profile字段问题咨询
核心原因
你当前拿到的返回结果直接是hits.hits层级的文档数组,说明响应外层的元数据(包含profile、took、_shards等字段)被上层逻辑/客户端默认过滤丢弃了,这是最常见的诱因,其他可能原因包括参数位置不兼容、响应过滤配置、客户端版本不匹配等。
排查解决步骤
第一步:验证原生ES请求返回是否正常
绕过当前使用的JS客户端,直接在Kibana Dev Tools或者用curl发送原生查询请求,确认ES服务端本身是否返回profile字段:GET my_index/_search { "size": 10, "profile": true, "query": { "bool": { "must": [ { "query_string": { "query": "*antonio* *banderas*", "fields": ["text"], "default_operator": "and" } } ] } } }如果该请求返回结果中存在
profile字段,说明问题完全出在JS客户端/上层封装逻辑,和ES服务端无关。第二步:调整客户端返回逻辑
你当前使用的客户端默认做了响应裁剪,只返回了文档数组。如果是官方@elastic/elasticsearch7.x版本客户端,原生返回结构为{ body: { hits: { hits: [...] }, profile: {...} }, statusCode: 200 },检查你的代码是否只提取了res.body.hits.hits,改为读取完整res.body即可拿到profile字段。
如果是第三方封装的ES客户端,查阅对应文档关闭默认的响应裁剪配置,开启完整响应返回。第三步:调整Profile参数位置
部分客户端对请求体顶层的profile参数识别存在兼容性问题,可以改为将参数放在请求URL参数层级:var query = { "index": "my_index", "size": 10, "profile": true // 移到query对象顶层,作为请求参数传递 }; var body = { "query": { "bool": { "must": [ { "query_string": { "query": "*antonio* *banderas*", "fields": [ "text" ], "default_operator": "and" } }] } } }; body.explain = false; // 删掉原来的body.profile = true配置 query.body = body; const res = await client.search(query);第四步:检查响应过滤配置
确认你的请求是否配置了filter_path参数,该参数会只返回指定路径的字段,如果仅配置了hits.hits相关路径,profile会被过滤,需要将profile加入过滤路径,示例:filter_path=hits.hits,profile,took。第五步:对齐客户端版本
确认你使用的ES JS客户端大版本和服务端7.14对齐,必须使用7.x版本的客户端,不要使用6.x或8.x版本,避免兼容性问题导致元字段丢失。
内容的提问来源于stack exchange,提问作者loretoparisi

