Elasticsearch【正则搜索】分析&实践
在ES中有很多使用不是很频繁的查询,可以达到一些特殊的效果。比如基于行为路径的漏斗模型。本篇就从使用上讲述一下正则表达式查询的用法。
Regexp Query
regexp允许使用正则表达式进行term查询.注意regexp如果使用不正确,会给服务器带来很严重的性能压力。比如.*开头的查询,将会匹配所有的倒排索引中的关键字,这几乎相当于全表扫描,会很慢。因此如果可以的话,最好在使用正则前,加上匹配的前缀。在正则中如果使用.*?或者+都会降低查询的性能。
注意:是term查询,也就是说这个查询不能跨term。
举个简单的例子:
GET /_search
{
"query": {
"regexp":{
"name.first": "s.*y"
}
}
}
正则支持的一些标准的用法:
搜索关键词的一部分
如果给定的term是abcde
ab.* 可以匹配
abcd 不可以匹配
也支持使用^或者$来指定开头或者结尾。
允许特殊字符
一些特殊字符是需要转义的,比如:
. ? + * | { } [ ] ( ) " \ # @ & < > ~
如果想要搜索某个固定的词,也可以加上双引号。
匹配任何字符
.可以匹配任意字符,比如
ab...
a.c.e
这几个都可以匹配abcde
匹配一个或者多个
使用+表示匹配一个或者多个字符
a+b+ # match
aa+bb+ # match
a+.+ # match
aa+bbb+ # match
上面这些都可以匹配aaabbb
匹配零个或者多个
a*b* # match
a*b*c* # match
.*bbb.* # match
aaa*bbb* # match
上面这些都可以匹配aaabbb
匹配另个或者一个
aaa?bbb? # match
aaaa?bbbb? # match
.....?.? # match
aa?bb? # no match
上面这些都可以匹配aaabbb
支持匹配次数
使用{}支持匹配指定的最小值和最大值区间
{5} # repeat exactly 5 times
{2,5} # repeat at least twice and at most 5 times
{2,} # repeat at least twice
比如对于字符串:
a{3}b{3} # match
a{2,4}b{2,4} # match
a{2,}b{2,} # match
.{3}.{3} # match
a{4}b{4} # no match
a{4,6}b{4,6} # no match
a{4,}b{4,} # no match
捕获组
对于字符串ababab
(ab)+ # match
ab(ab)+ # match
(..)+ # match
(...)+ # no match
(ab)* # match
abab(ab)? # match
ab(ab)? # no match
(ab){3} # match
(ab){1,2} # no match
选择运算符
支持或操作的匹配,注意这里默认都是最长匹配的。
aabb|bbaa # match
aacc|bb # no match
aa(cc|bb) # match
a+|b+ # no match
a+b+|b+a+ # match
a+(b|c)+ # match
字符匹配
支持在[]中进行字符匹配,^代表非的意思
[abc] # 'a' or 'b' or 'c'
[a-c] # 'a' or 'b' or 'c'
[-abc] # '-' or 'a' or 'b' or 'c'
[abc\-] # '-' or 'a' or 'b' or 'c'
[^abc] # any character except 'a' or 'b' or 'c'
[^a-c] # any character except 'a' or 'b' or 'c'
[^-abc] # any character except '-' or 'a' or 'b' or 'c'
[^abc\-] # any character except '-' or 'a' or 'b' or 'c'
其中-代表的范围匹配。
可选的匹配符
在正则表达式中也支持一些特殊的操作符,可以使用flags字段控制是否开启。
Complement
这个表示正则表示匹配一段字符串,比如ab~cd意思是:a开头,后面是b,然后是一堆非c的字符串,最后以d结尾。比如字符串abcdef
ab~df # match
ab~cf # match
ab~cdef # no match
a~(cb)def # match
a~(bc)def # no match
Interval
interval选项支持数值的范围,比如字符串foo80:
foo<1-100> # match
foo<01-100> # match
foo<001-100> # no match
Intersection
使用&可以实现多个匹配的连接,比如字符串aaabbb:
aaa.+&.+bbb # match
aaa&bbb # no match
Any
使用@,可以匹配任意的字符串
实践
首先创建索引:
PUT test
然后创建映射:
PUT test/_mapping/test
{
"properties": {
"a": {
"type": "string",
"index":"not_analyzed"
},
"b":{
"type":"string"
}
}
}
添加一条数据:
PUT test/test/1
{
"a":"a,b,c","b":"a,b,c"
}
先来分析一下,a,b,c被默认分析成了什么?
POST test/_analyze
{
"analyzer": "standard",
"text": "a,b,c"
}
返回内容:
{
"tokens": [
{
"token": "a",
"start_offset": 0,
"end_offset": 1,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "b",
"start_offset": 2,
"end_offset": 3,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "c",
"start_offset": 4,
"end_offset": 5,
"type": "<ALPHANUM>",
"position": 2
}
]
}
然后查询一下:
POST /test/test/_search?pretty
{
"query":{
"regexp":{
"a": "a.*b.*"
}
}
}
返回
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "test",
"_type": "test",
"_id": "1",
"_score": 1,
"_source": {
"a": "a,b,c",
"b": "a,b,c"
}
}
]
}
}
再换成b字段试试:
POST /test/test/_search?pretty
{
"query":{
"regexp":{
"b": "a.*b.*"
}
}
}
返回
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 0,
"max_score": null,
"hits": []
}
}
这是为什么呢?
因为整个regexp查询是应用到一个词上的,针对某个词,搜索a.*b.*,a字段由于不分词,它的词是整个的a.b.c;b字段经过分词,他的词是a和b和c三个独立的词,因此针对a字段的正则搜索可以查询到结果;但是针对b字段却搜索不到。
归纳起来,还是需要好好理解分词在搜索引擎中的作用才行。
参考
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html
Elasticsearch【正则搜索】分析&实践的更多相关文章
- fluentd结合kibana、elasticsearch实时搜索分析hadoop集群日志<转>
转自 http://blog.csdn.net/jiedushi/article/details/12003171 Fluentd是一个开源收集事件和日志系统,它目前提供150+扩展插件让你存储大数据 ...
- 基于 Kafka 的实时数仓在搜索的实践应用
一.概述 Apache Kafka 发展至今,已经是一个很成熟的消息队列组件了,也是大数据生态圈中不可或缺的一员.Apache Kafka 社区非常的活跃,通过社区成员不断的贡献代码和迭代项目,使得 ...
- Elasticsearch源码分析 - 源码构建
原文地址:https://mp.weixin.qq.com/s?__biz=MzU2Njg5Nzk0NQ==&mid=2247483694&idx=1&sn=bd03afe5a ...
- elasticsearch源码分析之search模块(server端)
elasticsearch源码分析之search模块(server端) 继续接着上一篇的来说啊,当client端将search的请求发送到某一个node之后,剩下的事情就是server端来处理了,具体 ...
- elasticsearch源码分析之search模块(client端)
elasticsearch源码分析之search模块(client端) 注意,我这里所说的都是通过rest api来做的搜索,所以对于接收到请求的节点,我姑且将之称之为client端,其主要的功能我们 ...
- Elasticsearch集成Hadoop最佳实践.pdf(内含目录)
Elasticsearch服务器开发(第2版) 介绍: ElasticSearch是一个开源的分布式搜索引擎,具有高可靠性,支持非常多的企业级搜索用例.ElasticsearchHadoop作为一个完 ...
- Elasticsearch分布式搜索
ElasticSearch之介绍 一 Elasticsearch产生背景 1.1 大规模数据如何检索 如:当系统数据量上了10亿.100亿条的时候,我们在做系统架构的时候通常会从以下角度去考虑问题:1 ...
- 十九种Elasticsearch字符串搜索方式终极介绍
前言 刚开始接触Elasticsearch的时候被Elasticsearch的搜索功能搞得晕头转向,每次想在Kibana里面查询某个字段的时候,查出来的结果经常不是自己想要的,然而又不知道问题出在了哪 ...
- 腾讯健康码16亿亮码背后的Elasticsearch系统调优实践【>>戳文章免费体验Elasticsearch服务30天】
[活动]Elasticsearch Service免费体验馆>>Elasticsearch Service新用户特惠狂欢低至4折>>Elasticsearch Service企 ...
随机推荐
- Vue学习之路---No.6(分享心得,欢迎批评指正)
我们还是先回顾一下上一次的重点: 1.事件绑定,我们可以对分别用方法和js表达式对事件进行处理 2.当方法名带括号的时候,在方法中一定要传参:而不带括号的时候,vm会自动配置默认event 3.各类事 ...
- okhttp +fastJson 在UI层的回调封装
一直使用OkHttp 经常烦人的地方是回调方法 数据解析后必须通过handler 在主线程做操作 网上找了很多资料 发现有些都是基于Gson做的解析 fastJson 在封装时 泛型传入会有很多不方 ...
- 【转】Objective-C Runtime
之前在找Runtime资料,这篇条理是相对比较清晰,对我最有启发的一篇,转载以作记录. 对于iOS小白,值得多看几遍,会有不少收获. --------------------------------- ...
- CSS -- 练习(待续优化)
啊啊啊 错误百出啊 错点总结: 字符全角半角.清楚浮动.结尾</div>有点乱找不到对应的了.注释要写好. <!DOCTYPE html> <html lang=&qu ...
- datagrid-detailview.js easyui表格嵌套
datagrid-detailview.js easyui表格嵌套
- oStrictHostKeyChecking=no 参数
应用在脚本当中,避免使用域名链接服务器的时候,检查knows_hosts文件
- 走入PHP-初次见面
FROM:实验楼 Linux启动WEB服务器: $ sudo service apache2 start 新建并打开test.php文件: $ sudo gvim /path/test.php PHP ...
- [敏捷开发实践](2) 用于开发和维持复杂产品的敏捷开发框架Scrum
[敏捷开发实践](2) 用于开发和维持复杂产品的敏捷开发框架Scrum 1,Scrum概述 上篇中提到敏捷开发有两种主流的方法,一个是XP,另一个是Scrum,本篇简要介绍Scrum方法.Scrum是 ...
- The superclass “javax.servlet.http.HttpServlet" was not found on the Java Build Path错误
1.异常信息 创建maven web项目时,出现 The superclass "javax.servlet.http.HttpServlet" was not found on ...
- STM32GPIO口8种模式细致分析(类比51单片机)
关于STM32GPIO口的8种工作模式,我们先引出一些问题? STM32GPIO口如果既要输入又要输出怎么办? 1.浮空输入模式 上图红色的表示便是浮空输入的过程,外部输入时0读出的就是0,外部输入时 ...