Elasticsearch基础(四):Elasticsearch语法与案例介绍

文章目录

Elasticsearch语法与案例介绍

[一、Restful API](#一、Restful API)

二、查询语法

1、ES分词器

2、ES查询

2.1、match

2.2、match_phrase

2.3、multi_match

2.4、term

2.5、terms

2.6、fuzzy

2.7、range

2.8、bool


Elasticsearch语法与案例介绍

一、Restful API

Elasticsearch采用REST API,所有的操作都可通过REST API完成,例如增删改查、别名配置等。

Elasticsearch官方参考文档

单文档API:

多文档API:

二、查询语法

1、ES分词器

对于存入ES索引(Index)中的各个字段(Term),ES内部都会有一个分词器对其进行分词,然后将这个分词结果存储起来,方便未来的查询使用,这个分词器用户也可以直接很方便的调用,只要访问其_analyze即可:

在学习查询语法之前需要了解一下ES的分词器。因为这是ES搜索引一个很大的特点,它查询速度之所以这么快也和这个有很大关系。但更重要的是,如果不了解ES会对存储的索引文本或者查询query进行分词,后面的语法将很难理解。

cpp 复制代码
GET _analyze
{
  "analyzer": "standard",
  "text": "This is a test doc"
}

这里需要指定一个分词器,ES默认的分词器是standard,不过只支持英文分词,如果用它来对中文进行分词的话会直接按字拆分,有一些中文分词器可以下载使用,像ik或者jieba之类的。

**注意:**阿里云ES内置了ik分词器,直接指定analyzer为ik_smart即可使用。

用上述的分词请求返回的结果如下

可以看到句子被分词器这样做好了分词,还有偏移量之类的信息。这里只是看一下ES是如何做到分词的,用户平时查询的话自己是用不到分词的,这些分词都是在保存索引时ES自动分好存储起来的。

总结:

  • Elasticsearch调用分词器的命令是GET _analyze
  • Elasticsearch默认的分词器是standard

2、ES查询

下面介绍一下ES常用的几种查询,详细的可以参考官网

Query DSL | Elasticsearch Guide [8.5] | Elastic

2.1、match

ES的查询有一个很大的特点就是分词。所以用户在使用ES的过程中脑子要始终有这么一个意识,要查找的text是通过分词器分过词的,所以去匹配的实际上是一个个被分词的片段。 而搜索的query也有可能会被分词,match就是一种会将用户搜索的query进行分词的查询方法。结合例子来看, 比如要查询的索引结构如下:

  • _index代表索引名称
  • _id代表该条数据唯一id
  • _source代表该条数据具体的结构

案例

cpp 复制代码
-- 创建索引
PUT /textbook
{
  "settings": {
    "number_of_shards": 5,
    "number_of_replicas": 1
  },
  "mappings": {
      "properties": {
        "bookName": {
          "type": "text",
          "analyzer": "standard"
        },
        "author":{
          "type":"text"
        },
        "num": {
          "type": "integer"
        }
    }
  }
}
cpp 复制代码
-- 插入数据
POST /textbook/_doc/kIwXeYQB8iTYJNkI986Y
{
        "bookName": "this is a test doc",
        "author": "老坛",
        "num": 20
    }

输入query语句如下:

cpp 复制代码
GET /textbook/_search
{
  "query": {
    "match": {
      "bookName":"test"
    }
  }
}

该条语句代表用match方式搜索索引为textbook中bookName可以匹配到test的语句。因为"bookName": "this is a test doc"原文被分词器分词后包含test这个词语,所以可以正常被匹配出来。

上面例子比较简单,看个复杂一点的例子

cpp 复制代码
GET /textbook/_search
{
  "query": {
    "match": {
      "bookName":"my test"
    }
  }
}

这个能否被匹配出来呢?原文中根本就没有my这个词语,那怎么被匹配出来?

但实际上是可以匹配出来的。原因是match查询里,会对查询的query也进行分词,也就是会将"my test"进行分词,得到my与test两个词语,然后用这两个词语分别去匹配文本,发现虽然my匹配不到,但是test可以匹配到,所以依然可以查出来。这个和传统的搜索方式确实存在差异,用户要注意。

那这种搜索方式存在的价值是什么呢?

其实还有蛮大用处的。比如ES库存储的是很多的英文好词好句,然后用户想提高自己的英文写作,因此想搜索出一些比较好的表达加在自己的文章中,那这个时候对于用户来讲,严格的匹配方式大概率什么都搜不到,但是像match这样的搜索方式便非常合适。

例如有个好句是这样的:If at first you don't succeed, try again

然后用户用下面的方式搜索:If you don't success

用match就可以很好的匹配出来。

总结:

Elasticsearch中math查询的特点是会对query进行分词,拿到分好的词去进行匹配文本,而不是将query进行整体匹配。

2.2、match_phrase

既然match的限制比较小,那如果需要限制更强一点用什么方式呢?match_phrase便是一个比较不错的选择。match_phrase和match一样也是会对搜索query进行分词,但是,不同的是它不是匹配到某一处分词的结果就算是匹配成功了,而是需要query中所有的词都匹配到,而且相对顺序还要一致,而且默认还是连续的,如此一来,限制就更多了。还是举个例子,对于刚刚的索引数据,如果还用刚刚的方式搜索:

cpp 复制代码
GET /textbook/_search
{
  "query": {
    "match_phrase": {
      "bookName":"my test"
    }
  }
}

这次是匹配不到结果的。那么怎样才能匹配到结果呢?

只能是搜索原文中的连续字串:

cpp 复制代码
GET /textbook/_search
{
  "query": {
    "match_phrase": {
      "bookName":"is a test"
    }
  }
}

这样是可以匹配到结果的。但是如此一来限制可能太大了一点,所以官方还给了一个核心参数可以调整搜索的严格程度,这个参数叫slop。

举个例子

cpp 复制代码
GET /textbook/_search
{
  "query": {
    "match_phrase": {
      "bookName":{
        "query":"is test",
        "slop":1
      }
    }
  }
}

比如将slop置为1,然后搜索"is test",虽然is test中间省略了一个词语"a",但是在slop为1的情况下是可以容忍中间省略一个词语,也可以搜索出来结果。以此类推,slop为2就可以省略两个词语了。用户可以根据自己的实际情况进行调整。

2.3、multi_match

有了前面的基础,multi_match比较好理解。实际上就是可以从多个字段中去寻找要查找的query:

cpp 复制代码
GET /textbook/_search
{
  "query": {
    "multi_match": {
        "query" : "老坛",
        "fields" : ["bookName", "author"]
    }
  }
}

比如这里是从bookName和author两个字段里去寻找老坛,虽然bookName没有,但是author可以匹配到,那也可以找到数据。所以本质上就是对bookName和author分别做了一次match。

总结:

  • Elasticsearch中match_phrase查询的特点是它不是匹配到某一处分词的结果就算是匹配成功了,而是需要query中所有的词都匹配到,而且相对顺序还要一致,而且默认还是连续的。
  • Elasticsearch中multi_match查询的特点是从多个字段中去寻找要查找的query。
2.4、term

term查询也是比较常用的一种查询方式,它和match的唯一区别就是match需要对query进行分词,而term是不会进行分词的,它会直接拿query整体和原文进行匹配。所以不理解的小伙伴使用起来可能会非常奇怪:

cpp 复制代码
GET /textbook/_search
{
  "query": {
    "term": {
      "bookName": "this is a test doc"
    }
  }
}

当用这种方式进行搜索时,明明要搜索的和被搜索的文本一模一样,但就是搜不出来。这就是因为去搜的实际上并不是原文本身,而是被分词的原文,在原文被分好的每一个词语里,没有一个词语是:"this is a test doc",那自然是什么都搜不到了。所以在这种情况下就只能用某一个词进行搜索才可以搜到:

cpp 复制代码
GET /textbook/_search
{
  "query": {
    "term": {
      "bookName": "this"
    }
  }
}
2.5、terms

terms查询事实上就是多个term查询取一个交集,也就是要满足多个term查询条件匹配出来的结果才可以查到,所以是比单纯的term条件更为严格了:

cpp 复制代码
GET /textbook/_search
{
  "query": {
    "terms": {
      "bookName": ["this", "is"]
    }
  }
}

比如这个例子,是要求原文中既有this这个词,又有is这个词才可以被查到,那按照这个规则是可以匹配到数据的。但是如果改成了一个不存在的词便匹配不到了。

cpp 复制代码
GET /textbook/_search
{
  "query": {
    "terms": {
      "bookName": ["this", "my"]
    }
  }
}

总结:

  • Elasticsearch中term查询的特点是term是不会进行分词的,它会直接拿query整体和分词后的原文进行匹配。
  • Elasticsearch中terms查询的特点是查询事实上就是多个term查询取一个交集,也就是要满足多个term查询条件匹配出来的结果,只要有一个匹配成功就返回。
2.6、fuzzy

fuzzy是ES里面的模糊搜索,它可以借助term查询来进行理解。fuzzy和term一样,也不会将query进行分词,但不同的是它在进行匹配时可以容忍词语拼写错误,至于容忍度如何,是根据参数fuzziness决定的。fuzziness默认是2,也就是在默认情况下,fuzzy查询容忍有两个字符及以下的拼写错误。即如果要匹配的词语为test,但是query是text,那也可以匹配到。这里无论是错写多写还是少写都是计算在内的。

同样还是举例说明,对于之前索引数据,如果查询语句为:

cpp 复制代码
GET /textbook/_search
{
  "query": {
    "fuzzy": {
      "bookName":"text"
    }
  }

这时肯定是用text来匹配原文中的每一个词,发现text和test最为接近,但是有一个字符的差异,在默认fuzziness为2的情况下,依然可以匹配出来。

当然这个fuzziness是可以调的,比如:

cpp 复制代码
GET /textbook/_search
{
  "query": {
    "fuzzy": {
      "bookName":{
        "value":"texts",
        "fuzziness":1
      }
    }
  }
}

在容忍度为1的情况下,如果想查texts就查不到结果了。

2.7、range

range查询时对于某一个数值字段的大小范围查询,range的语法设计到了一些关键字:

  • gte:大于等于
  • gt:大于
  • lt:小于
  • lte:小于等于
cpp 复制代码
GET /textbook/_search
{ 
  "query": {
    "range": { 
      "num": { 
          "gte":20, 
          "lt":30 
      } 
    }
  } 
}

比如这样的条件就是去查找字段num大于等于20小于30的数据,那数据便可以被查询到。

2.8、bool

bool查询是上面查询的一个综合,它可以用多个上面的查询去组合出一个大的查询语句,它也有一些关键字:

  • must:代表且的关系,也就是必须要满足该条件
  • should:代表或的关系,代表符合该条件就可以被查出来(满足其中部分条件)
  • must_not:代表非的关系,也就是要求不能是符合该条件的数据才能被查出来
cpp 复制代码
GET /textbook/_search
{
    "query":{
        "bool":{
            "must":{
                "match":{
                    "author":"老坛"
                }},
            "should":[
                {
                  "term":{
                    "bookName":"老坛"
                }},
                {
                  "range":{
                    "num":{
                        "gt":10
                    } }}
            ]
            , "minimum_should_match" : 1
        }}}

这里就要求must里面的match是必须要符合的,但是should里面的条件符合一条即可。

注意:minimum_should_match 参数指定should返回的文档必须匹配的子句的数量或百分比。如果bool查询包含至少一个should子句,而没有must或filter子句,则默认值为1。否则,默认值为0。

总结:

  • Elasticsearch中fuzzy查询的特点是fuzzy是ES里面的模糊搜索,允许词语发生一定的拼写错误。
  • Elasticsearch中range查询的特点是范围查询:gte、gt、lt、lte。
  • Elasticsearch中bool查询的特点是查询逻辑组合,可以用使用一些小查询去组合出一个大的查询语句。

  • 📢博客主页:https://lansonli.blog.csdn.net
  • 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
  • 📢本文由 Lansonli 原创,首发于 CSDN博客🙉
  • 📢停下休息的时候不要忘了别人还在奔跑,希望大家抓紧时间学习,全力奔赴更美好的生活✨
相关推荐
故乡de云18 分钟前
Google Cloud与AWS大数据AI服务对比:2026年企业选型指南
大数据·人工智能·aws
米粒144 分钟前
操作系统原理--处理机调度
大数据
数说星榆1811 小时前
在线高清泳道图制作工具 无水印 PC
大数据·人工智能·架构·机器人·流程图
老胡全房源系统1 小时前
2026年1月适合房产经纪人用的房产中介管理系统
大数据·人工智能·房产经纪人培训
老陈头聊SEO1 小时前
生成引擎优化(GEO)在提升内容创作质量与用户体验中的重要作用与策略探讨
其他·搜索引擎·seo优化
杭州龙立智能科技2 小时前
专业的厂内运输车智能化厂家
大数据·人工智能·python
securitypaper2 小时前
2026年最新发布的 安全生产 行业标准 列表 下载
大数据·安全
Light602 小时前
从“报告”到“能力”——构建智能化、可审计的数据治理闭环——领码 SPARK 数据质量平台白皮书
大数据·分布式·spark
TDengine (老段)2 小时前
嘉环科技携手 TDengine,助力某水务公司构建一体化融合平台
大数据·数据库·科技·物联网·时序数据库·tdengine·涛思数据
程序猿阿伟2 小时前
《Python生态事件溯源与CQRS轻量化落地指南》
大数据·python·微服务