ElasticSearch range(范围查询)

本文介绍了Elasticsearch中的范围查询,包括数字、日期和字符串类型的范围过滤。通过示例展示了如何进行数字和日期的范围操作,并强调了字符串范围在低基数字段上的适用性。此外,还提及Elasticsearch自2016年起使用BKD树算法对不同字段类型进行优化索引,提高查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Range类型设置
Elasticsearch 支持多种范围类型

• 数值类型
• 日期类型
• IP地址类型

1、数字范围

到目前为止,对于数字,只介绍如何处理精确值查询。实际上,对数字范围进行过滤有时会更有用。例如,我们可能想要查找所有价格大于 $20 且小于 $40 美元的产品。

在 SQL 中,范围查询可以表示为:

SELECT document
FROM   products
WHERE  price BETWEEN 20 AND 40

Elasticsearch 有 range 查询,不出所料地,可以用它来查找处于某个范围内的文档:

GET /my_store/products/_search
{
    "query" : {
        "constant_score" : {
            "filter" : {
                "range" : {
                    "price" : {
                        "gte" : 20,
                        "lt"  : 40
                    }
                }
            }
        }
    }
}

range 查询可同时提供包含(inclusive)和不包含(exclusive)这两种范围表达式,可供组合的选项如下:

gt: > 大于(greater than)
lt: < 小于(less than)
gte: >= 大于或等于(greater than or equal to)
lte: <= 小于或等于(less than or equal to)

如果想要范围无界(比方说 >20 ),只须省略其中一边的限制:

"range" : {
    "price" : {
        "gt" : 20
    }
}

2、日期范围

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"
    }
}

日期计算还可以被应用到某个具体的时间,并非只能是一个像 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) 的,所以它不仅知道每月的具体天数,还知道某年的总天数(闰年)等信息。更详细的内容可以参考: 时间格式参考文档

3、字符串范围

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) 字段(即只有少量唯一词项)时可以正常工作,但是唯一词项越多,字符串范围的计算会越慢。

4、
Elasticsearch 从 2016 年引入了 BKD 树算法,在构建索引时会依据字段类型设置不同的算法实现,无需要人工干预,只要设计正确的类型,如下

• 若是字符类型的,基于 Inverted Index 构建索引
• 若是数值类型,基于 BKD-Tree 构建索引

Bkd-Tree 作为一种基于 K-D-B-tree 的索引结构,用来对多维度的点数据 (multi-dimensional point data) 集进行索引。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值