在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字段经过分词,他的词是abc三个独立的词,因此针对a字段的正则搜索可以查询到结果;但是针对b字段却搜索不到。

归纳起来,还是需要好好理解分词在搜索引擎中的作用才行。

参考

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html

Elasticsearch【正则搜索】分析&实践的更多相关文章

  1. fluentd结合kibana、elasticsearch实时搜索分析hadoop集群日志<转>

    转自 http://blog.csdn.net/jiedushi/article/details/12003171 Fluentd是一个开源收集事件和日志系统,它目前提供150+扩展插件让你存储大数据 ...

  2. 基于 Kafka 的实时数仓在搜索的实践应用

    一.概述 Apache Kafka 发展至今,已经是一个很成熟的消息队列组件了,也是大数据生态圈中不可或缺的一员.Apache Kafka 社区非常的活跃,通过社区成员不断的贡献代码和迭代项目,使得 ...

  3. Elasticsearch源码分析 - 源码构建

    原文地址:https://mp.weixin.qq.com/s?__biz=MzU2Njg5Nzk0NQ==&mid=2247483694&idx=1&sn=bd03afe5a ...

  4. elasticsearch源码分析之search模块(server端)

    elasticsearch源码分析之search模块(server端) 继续接着上一篇的来说啊,当client端将search的请求发送到某一个node之后,剩下的事情就是server端来处理了,具体 ...

  5. elasticsearch源码分析之search模块(client端)

    elasticsearch源码分析之search模块(client端) 注意,我这里所说的都是通过rest api来做的搜索,所以对于接收到请求的节点,我姑且将之称之为client端,其主要的功能我们 ...

  6. Elasticsearch集成Hadoop最佳实践.pdf(内含目录)

    Elasticsearch服务器开发(第2版) 介绍: ElasticSearch是一个开源的分布式搜索引擎,具有高可靠性,支持非常多的企业级搜索用例.ElasticsearchHadoop作为一个完 ...

  7. Elasticsearch分布式搜索

    ElasticSearch之介绍 一 Elasticsearch产生背景 1.1 大规模数据如何检索 如:当系统数据量上了10亿.100亿条的时候,我们在做系统架构的时候通常会从以下角度去考虑问题:1 ...

  8. 十九种Elasticsearch字符串搜索方式终极介绍

    前言 刚开始接触Elasticsearch的时候被Elasticsearch的搜索功能搞得晕头转向,每次想在Kibana里面查询某个字段的时候,查出来的结果经常不是自己想要的,然而又不知道问题出在了哪 ...

  9. 腾讯健康码16亿亮码背后的Elasticsearch系统调优实践【>>戳文章免费体验Elasticsearch服务30天】

    [活动]Elasticsearch Service免费体验馆>>Elasticsearch Service新用户特惠狂欢低至4折>>Elasticsearch Service企 ...

随机推荐

  1. iTunes Documents 文件共享指导手册

    金田 p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Helvetica; min-height: 13.0px } p.p2 { margi ...

  2. PHP后台程序员工作到如今的一点心得

    一个项目的建立,一开始一定要有需求文档,没有需求文档的项目注定会改来改去.还被骂的很惨.要时刻牢记一句话:口说无凭,有文档为证. 第一:开发语言的选择,PHP,当然还有JAVA,.NET你做的项目当然 ...

  3. Entity Framework — ( Database First )

    什么是Entity Framework Entity Framework是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案.将数据存储从域对象自动映射到关系 ...

  4. csvkit---python一个牛逼到不行的csv处理库

    先吐槽一下:不管是百度还是谷歌,查来查去除了官方文档之外就没有任何可以借鉴的例子,虽然官方文档写的挺好的.但是我一直以为是在python语言的方式运行的,结果是以命令行的方式运行的,搞得我还以为这个库 ...

  5. swig编译GDAL的C#库时遇到的代码安全问题及解决方法

    之前一直用的是别人编译好的gdal库开发,今天自己编译了gdal的2.0.0版本,踩了不少坑,但总算解决了. 编译方法主要参考http://blog.csdn.net/liminlu0314/arti ...

  6. js求三位数的和

    例如输入508就输出5+0+8的和13: <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  7. 【转】Flash字体嵌入方法

    原文链接:http://www.cnblogs.com/ddw1997/archive/2011/11/13/2247546.html 一.如果使用flash cs5.5 1.先新建一个字体fla文件 ...

  8. 性能调优:mysql之left join

    poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821478,咨询电话010-845052 ...

  9. JavaScript变量相关问题

    本文重在探讨JavaScript变量包含的两种不同数据类型的值--基本类型值和引用类型值的区别.在此外稍微带过ECMAScript和JavaScript的关系. 题为JavaScript变量,但更具体 ...

  10. css锚点ios不兼容的方法

    css锚点的正常方法: <a href="#1f"></a> <a name="1f"></a> ios出现的问 ...