Node.js+GraphQL+Elasticsearch:mapping无单复数标识致数组返回异常
问题背景
Elasticsearch mapping 本身不存储字段单复数的相关标识,因此业务侧约定规则:单数形式的propName返回单个值或数组首项,复数形式的propNameA返回完整值数组。
当前开发场景下传入对象数组时,GraphQL 未按预期返回对象数组,仅返回单个对象,可按以下步骤排查解决:
排查步骤与对应解决方案
- 核对GraphQL Schema类型定义
首先检查对应字段的Schema声明,数组类型字段必须用方括号包裹对应类型,比如用户对象数组的正确声明是[User!]!,如果漏写方括号直接写User!,GraphQL执行层会自动对返回值做类型裁剪,遇到数组时只会保留第一个元素返回。修正Schema里的类型声明后重新加载服务即可。 - 检查Resolver层的返回逻辑
对照约定的单复数字段规则,逐一排查对应字段的解析函数:- 确认字段名是否符合复数命名规则,是否因为拼写偏差触发了单数字段取首项的逻辑分支
- 排查代码中是否存在误写的取首项逻辑,比如拿到ES返回结果直接写了
return res[0],或是写了数组解构const [item] = queryResult后直接返回单个对象的问题 - 如果项目内实现了针对单数字段的通用返回处理逻辑,检查规则判定范围是否过宽,误命中了当前复数字段
- 验证Elasticsearch原始查询结果
全量打印ES查询的原始响应日志,确认ES层面是否返回了完整数组:- 检查查询语句是否误加
size: 1这类限制返回条数的参数 - 如果查询的是嵌套对象数组,核对对应字段的ES mapping是否声明为
nested类型,未声明nested类型的嵌套对象会被扁平化存储,查询时大概率只返回第一个匹配的子文档,这类情况需要先将mapping修正为nested类型,重建索引重新导入数据后再验证
- 检查查询语句是否误加
- 排查通用类型转换插件逻辑
如果项目中使用了自动将ES返回结果转换为GraphQL类型的公共中间件或自研插件,检查插件内的单复数判断逻辑是否存在bug,比如复数后缀匹配规则不全、大小写判断逻辑错误,导致复数字段被识别为单数字段,自动执行了取首项操作。可以直接在转换逻辑分支添加debug日志,确认字段的识别结果是否符合预期,快速定位问题。
内容的提问来源于stack exchange,提问作者tycoon74
相关产品推荐
相关产品推荐

