最近开始玩 elasticsearch,刚玩到 flattened 时,发现它文档里面有这么一句话 :
only basic queries are allowed, with no support for numeric range queries or highlighting.
此类型只提供基本查询,不提供numeric的range查询以及高亮。
可是,当我往下翻阅文档的时候,发现它支持的类型中出现了range?Supported Operations
term, terms, and terms_setprefixrangematch and multi_matchquery_string and simple_query_stringexists
这是怎么回事呢?好奇使我成长~
分析继续查阅文档,不经意间我们看到了这么一句话。
it treats all values as keywords。
flattened 会将所有的值都以 keywords 进行存储 (所以数字的存储也会是keyword,时间类型也并不会自动转成timestamp进行存储)
那么博主猜测,是不是因为它将所有的值都转成了keyword,所以才不支持 numeric range的?毕竟keyword时可以进行对比的,但是它是按照 ascii 码逐一进行对比,那么数字转成 keyword后,确实对比的值会不正确?ascii码表
那么我们来验证这一猜测。
首先创建一个带有 flattened 的mapping
PUT flattened_range{ "mappings": { "properties": { "title": { "type": "text" }, "labels": { "type": "flattened" } } }}
再添加几条数据!!
POST flattened_range/_doc/1{ "title": "flattened range 1.", "labels": { "number": 20, "time": "2022-02-12 11:35:09" }}POST flattened_range/_doc/2{ "title": "flattened range 2.", "labels": { "number": 80, "time": "2022-02-12 11:36:09" }}POST flattened_range/_doc/3{ "title": "flattened range 3.", "labels": { "number": 100, "time": "2022-02-12 11:37:09" }}POST flattened_range/_doc/4{ "title": "flattened range 4.", "labels": { "number": 130, "time": "2022-02-12 11:38:09" }}
那么,接下来我们进行数据查询:
GET flattened_range/_search{ "query": { "bool": { "filter": [ { "range": { "labels.number": { "gte": 10, "lt": 90 } } } ] } }}
查询结果是 20 80 100 130 都被查询出来了,这是因为字符串中的ascii码逐一对比,这些结果的首字母都大于等于1,小于等于9。
再查一次:
GET flattened_range/_search{ "query": { "bool": { "filter": [ { "range": { "labels.number": { "gte": 10, "lt": 15 } } } ] } }}
查询结果是 100 130 符合猜测预期!!!
结论flattend 的 range 查询是针对keyword进行查询,逐个对比ascii码进行过滤,在数字转成 keyword的情况下,结果会不准确。