Elasticsearch范围查询range
实际上,对数字范围进行过滤有时会更有用。例如,我们可能想要查找所有价格大于 $20 且小于 $40 美元的产品。
在 SQL 中,范围查询可以表示为: SELECT document FROM products WHERE price BETWEEN 20 AND 40
Elasticsearch 有 range 查询,不出所料地,可以用它来查找处于某个范围内的文档:"range" : { "price" : { "gte" : 20, "lte" : 40 } }
range 查询可同时提供包含(inclusive)和不包含(exclusive)这两种范围表达式,可供组合的选项如下:gt : > 大于(greater than)lt : < 小于(less than)gte : >= 大于或等于(greater than or equal to)lte : <= 小于或等于(less than or equal to)
下面是一个范围查询的例子:.GET /my_store/products/_search { "query" : { "constant_score" : { "filter" : { "range" : { "price" : { "gte" : 20, "lt" : 40 } } } } } }
如果想要范围无界(比方说 >20 ),只须省略其中一边的限制:"range" : { "price" : { "gt" : 20 } }
拷贝为 curl在 Sense 中查看日期范围
range 查询同样可以应用在日期字段上:"range" : { "timestamp" : { "gt" : "2014-01-01 00:00:00", "lt" : "2014-01-07 00:00:00" } }
当使用它处理日期字段时, range 查询支持对 日期计算(date math) 进行操作,比方说,如果我们想查找时间戳在过去一小时内的所有文档:"range" : { "timestamp" : { "gt" : "now-1h" } }
这个过滤器会一直查找时间戳在过去一个小时内的所有文档,让过滤器作为一个时间 滑动窗口(sliding window) 来过滤文档。
日期计算还可以被应用到某个具体的时间,并非只能是一个像 now 这样的占位符。只要在某个日期后加上一个双管符号 (|| ) 并紧跟一个日期数学表达式就能做到:"range" : { "timestamp" : { "gt" : "2014-01-01 00:00:00", "lt" : "2014-01-01 00:00:00||+1M" } }
早于 2014 年 1 月 1 日加 1 月(2014 年 2 月 1 日 零时)
日期计算是 日历相关(calendar aware) 的,所以它不仅知道每月的具体天数,还知道某年的总天数(闰年)等信息。字符串范围
range 查询同样可以处理字符串字段,字符串范围可采用 字典顺序(lexicographically) 或字母顺序(alphabetically)。例如,下面这些字符串是采用字典序(lexicographically)排序的:5, 50, 6, B, C, a, ab, abb, abc, b
在倒排索引中的词项就是采取字典顺序(lexicographically)排列的,这也是字符串范围可以使用这个顺序来确定的原因。
如果我们想查找从 a 到 b (不包含)的字符串,同样可以使用 range 查询语法:"range" : { "title" : { "gte" : "a", "lt" : "b" } }
注意基数
数字和日期字段的索引方式使高效地范围计算成为可能。但字符串却并非如此,要想对其使用范围过滤,Elasticsearch 实际上是在为范围内的每个词项都执行 term 过滤器,这会比日期或数字的范围过滤慢许多。
字符串范围在过滤 低基数(low cardinality) 字段(即只有少量唯一词项)时可以正常工作,但是唯一词项越多,字符串范围的计算会越慢。