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企 ...
随机推荐
- PHP服务器脚本 PHP内核探索:新垃圾回收机制说明
在5.2及更早版本的PHP中,没有专门的垃圾回收器GC(Garbage Collection),引擎在判断一个变量空间是否能够被释放的时候是依据这个变量的zval的refcount的值,如果refco ...
- 【Troubleshooting Case】Unable to delete Exchange database?
在我们日常邮件系统运维管理或实施部署变更中,经常会遇到,删除Exchange 数据库DB时,提示无法删除. ------------------– Microsoft Exchange Error - ...
- js 的DOM操作 2017-03-21
DOM(document object model) 文档对象模型 BOM(browse object model) 针对浏览器(如:弹出的窗口,滚动条等) 一.操作对象(注意大小写:注意elemen ...
- 整理:20个非常有用的Java程序片段
下面是20个非常有用的Java程序片段,希望能对你有用. 1. 字符串有整型的相互转换 String a = String.valueOf(2); //integer to numeric strin ...
- DataTable的AcceptChanges()方法和DataRow的RowState属性
这个属性是一个只读属性的枚举类型,一共有五个值,Detached,Unchanged,Added,Deleteed,Modified, 属性名 值 备注 Detached 1 已创建该行,但是该行不属 ...
- 通过取父级for循环的i来理解闭包,iife,匿名函数
在使用for循环的时候,假如需要在循环体中添加一个匿名函数处理其他的事情,那么,在这个匿名函数内,如果需要用到对应的i,因为闭包的缘故,循环体循环结束后才返回i,所以i最终为最后一次++的数值. ...
- 【iOS】7.4 定位服务->3.2 地图框架MapKit 功能2:路线规划(导航)
本文并非最终版本,如果想要关注更新或更正的内容请关注文集,联系方式详见文末,如有疏忽和遗漏,欢迎指正. 本文相关目录: ================== 所属文集:[iOS]07 设备工具 === ...
- Docker系列一之基础快速入门企业实战
1.1什么是LXC LXC为Linux Container的简写.Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚 ...
- Java面试指导
Java面试指导 想要成为合格的Java程序员或工程师到底需要具备哪些专业技能,面试者在面试之前到底需要准备哪些东西呢?本文陈列的这些内容既可以作为个人简历中的内容,也可以作为面试的时候跟面试官聊 ...
- Android多渠道打包
项目需要,简单2步实现(由于简单,所以对大量渠道打包不是最优的),比如1000个渠道同时打包的话可能花费的时间会过长.不过目前该方法能满足绝大需求了...根据截图一步一步走: 第一步 设置配置清单文件 ...