前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Elasticsearch:正确使用 regexp 搜索

Elasticsearch:正确使用 regexp 搜索

作者头像
腾讯云大数据
修改2021-01-08 16:13:06
3.5K0
修改2021-01-08 16:13:06
举报
文章被收录于专栏:腾讯云Elasticsearch Service

腾讯云 Elasticsearch Service】高可用,可伸缩,云端全托管。集成X-Pack高级特性,适用日志分析/企业搜索/BI分析等场景


Regular Expressions 搜索也即正则搜索是非常耗时的。正则表达式是一种使用 placeholder(称为运算符)匹配数据中的模式的方法。 有关regexp查询支持的运算符的列表,请参阅 Regular expression syntax

在今天的文章中,我们来简单介绍如何正确使用 regexp 搜索。

正则表达式语法中使用了许多符号和运算符来表示通配符和字符范围:

  • 句号 “.” 用于代表任何字符。
  • 用括号括起来的一系列字符,例如 [a-z],是一个字符类。 字符类表示字符范围; 在此示例中,它充当任何字母的替代。
  • 加号 “+” 用于表示重复的字符; 例如,“Mississippi” 中的 “pp”。

我们来看一个 “regexp”,其中包含我们刚刚讨论的所有正则表达式语法。 以下示例中显示的 regexp 将与单词 “Mississippi” 匹配:

代码语言:javascript
复制
GET states/_search{  "query": {    "regexp": {      "name": "[a-z]*ip+i"    }  }} # RETURNS --->"name" : "Mississippi"  GET states/_search{  "query": {    "regexp": {      "name": "mis+[a-z]*"    }  }}# RETURNS --->"name" : "Missouri"# ..and"name" : "Mississippi" GET states/_search{  "query": {    "regexp": {      "name": "[a-z]*ska"    }  }} # RETURNS -->"name" : "Alaska"# and.."name" : "Nebraska"

我们首先创建一个 my_example 的索引:

代码语言:javascript
复制
PUT my_example/_doc/1{  "content": "This is a good network"}

假如我们想搜索以 net 为开头的文档,那么我们可以使用 regexp 来进行如下写的搜索:

代码语言:javascript
复制
GET my_example/_search{  "query": {    "regexp": {      "content": "net.*"    }  }}

根据 Regular expression syntax 里的描述,它匹配任何以 net 为开头的所有的文档:

可能有人想搜索以 work 结束的术语的所有文档,那么我们应该怎么做呢?我们可以通过如下的方法:

代码语言:javascript
复制
GET my_example/_search{  "query": {    "regexp": {      "content": ".*work"    }  }}

显示的结果为:

我们得到了我们希望的结果。

虽然在上面我们得到我们想要的结果,但是在实际使用 regexp 搜索时,我们必须记住如下的事项:

  • 避免通配符在前面,比如上面的 .*work。可能以避免使用前导通配符的方式对数据建立索引
  • 通常,正则表达式可能会很昂贵

那么什么是正确的解决方案呢?

如果您确实需要匹配 token 的末尾,只需使用 reverse 过滤器为它们建立索引。下面,我们用一个具体的例子来实现。

首先,我们为 reverse_example 建立一个 mapping:

代码语言:javascript
复制
PUT reverse_example{  "settings": {    "analysis": {      "analyzer": {        "whitespace_reverse": {          "tokenizer": "whitespace",          "filter": [            "reverse"          ]        }      }    }  },  "mappings": {    "properties": {      "content": {        "type": "text",        "fields": {          "reversed": {            "type": "text",            "analyzer": "whitespace_reverse"          }        }      }    }  }}

在这里 content 是一个 multi-field 的字段。content.reversed 将使用 whitespace_reverse 分析器来对我们的字段进行分词。这个分析器将会对术语进行倒序处理。比如:

代码语言:javascript
复制
GET reverse_example/_analyze{  "tokenizer": "standard",  "filter": [    "reverse"  ],  "text": "quick fox jumps"}

它将返回:

代码语言:javascript
复制
{  "tokens" : [    {      "token" : "kciuq",      "start_offset" : 0,      "end_offset" : 5,      "type" : "<ALPHANUM>",      "position" : 0    },    {      "token" : "xof",      "start_offset" : 6,      "end_offset" : 9,      "type" : "<ALPHANUM>",      "position" : 1    },    {      "token" : "spmuj",      "start_offset" : 10,      "end_offset" : 15,      "type" : "<ALPHANUM>",      "position" : 2    }  ]}

现在,我们对我们的索引添加一个文档:

代码语言:javascript
复制
PUT reverse_example/_doc/1{  "content": "This is a good network"}

 那么我们对我们的文档重新使用 regexp 进行搜索:

代码语言:javascript
复制
GET reverse_example/_search{  "query": {    "regexp": {      "content.reversed": "krow.*"    }  }}

显示的结果为:

我们通过上面的方法把通配符在前面的搜索修改成为通配符在后面的 regexp 搜索。

参考:

【1】https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-reverse-tokenfilter.html


最新活动

包含文章发布时段最新活动,前往ES产品介绍页,可查找ES当前活动统一入口

Elasticsearch Service自建迁移特惠政策>>

Elasticsearch Service 新用户特惠狂欢,最低4折首购优惠 >>

Elasticsearch Service 企业首购特惠,助力企业复工复产>>

关注“腾讯云大数据”公众号,技术交流、最新活动、服务专享一站Get~

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 【腾讯云 Elasticsearch Service】高可用,可伸缩,云端全托管。集成X-Pack高级特性,适用日志分析/企业搜索/BI分析等场景
  • 最新活动
相关产品与服务
Elasticsearch Service
腾讯云 Elasticsearch Service(ES)是云端全托管海量数据检索分析服务,拥有高性能自研内核,集成X-Pack。ES 支持通过自治索引、存算分离、集群巡检等特性轻松管理集群,也支持免运维、自动弹性、按需使用的 Serverless 模式。使用 ES 您可以高效构建信息检索、日志分析、运维监控等服务,它独特的向量检索还可助您构建基于语义、图像的AI深度应用。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档