Elasticsearch _search及range范围查询返回结果错误问题
问题根因
全量查询仅返回10条结果
这是Elasticsearch的默认行为:未显式指定size参数时,普通查询默认最多返回10条命中结果,hits.total.value显示的16才是匹配条件的总文档数,不存在数据丢失。如果需要返回更多结果,给查询加上size参数即可,比如传size: 20就会返回前20条结果;单次查询默认最多返回10000条,超过这个量级需要用scroll或search_after做深度分页。
range范围查询结果不符合预期
核心问题是你没有提前定义索引映射(mapping),Elasticsearch自动生成的动态映射把money字段识别成了字符串类型,不是数值类型:
- 你贴的写入代码是从
_id=2开始的,但返回结果里存在_id=1的文档,说明你最早写入_id=1时,money字段传的是带引号的字符串格式数值,ES根据第一条写入的数据自动把money字段类型设成了字符串(text+keyword),后续写入的数值类型money值会被自动转成字符串存储,已经生成的字段类型不会被后续写入修改。 - 对字符串类型字段执行range查询时,比较规则是字符串字典序,不是数值大小:逐位对比字符ASCII码,比如
"10"、"100"的第二位字符是0,比"15"的第二位5小,"20"开头是2比1大,所以lte:100的条件只会匹配到字典序不大于"100"的三个值:10、10、100,和你拿到的返回结果完全吻合。
修复步骤
- 删除现有映射错误的索引:
DELETE tryDB
- 重建索引,显式指定字段类型,避免动态映射识别错误:
PUT tryDB { "mappings": { "properties": { "personId": {"type": "keyword"}, "minor": {"type": "boolean"}, "money": {"type": "integer"} } } }
- 重新写入所有文档,之后再执行range查询就能得到正确结果。
日常排查时可以用下面的命令查看索引的字段映射,提前确认类型是否符合预期:
GET tryDB/_mapping
内容的提问来源于stack exchange,提问作者Anshuman
相关产品推荐
相关产品推荐

