Elasticsearch从入门到精通-04ES高级语法

Elasticsearch从入门到精通-04ES简单语法

👏作者简介:大家好,我是程序员行走的鱼

📖 本篇主要介绍和大家一块学习一下ES部分高级语法DSL

Elasticsearch 提供了基于 JSON 提供完整的查询 DSL 来定义查询,接下来就基于我们关系型数据类比关系看看Elasticsearch是如何进行高级查询的

在进行高级查询之前,我们先创建索引指定分词器为ik分词器

json 复制代码
PUT /es_db
{
  "settings": {
    "index": {
      "analysis.analyzer.default.type": "ik_max_word"
    }
  }
}

1.1 无条件查询

无查询条件是查询所有,默认是查询所有的,或者使用match_all表示所有

语法:

json 复制代码
GET es_db/_doc/_search

示例:

1.2 匹配查询

匹配查询主要是针对文本类型的字段,文本类型的字段在建立索引的时候会对内容进行分词,当查询时,也会对搜索条件进行分词,然后通过倒排索引查找到匹配的数据

  • match:通过match关键词匹配条件内容
  • prefix : 前缀匹配
  • regexp : 通过正则表达式来匹配数据
  • wildcard:通过通配符来匹配数据

match匹配:

json 复制代码
GET es_db/_doc/_search
{
  "query":{
    "match":{
      "name" : "三"
    }
  }
}

前缀匹配:

json 复制代码
GET es_db/_doc/_search
{
  "query":{
      "prefix": {
       "name.keyword": {
        "value": "张"
      }
    }
  }
}

正则匹配:

json 复制代码
GET es_db/_doc/_search
{
  "query": {
   "regexp": {
      "name": ".*op[A-z]{0,1}"
    }
  }
}

通配符匹配:

json 复制代码
GET es_db/_doc/_search
{
  "query": {
    "wildcard": {
      "name": {
        "value": "张*"
      }
    }
  }
}

前缀匹配搜索, 正则表达式匹配搜索, 通配符匹配搜索等等,但是这种模糊匹配都不建议在生产中使用,因为都需要扫描整个doc的索引,所以效率很低,所以不建议生产中使用

match条件还支持以下参数:

  • query : 指定匹配的值

  • operator : 匹配条件类型

  • and : 条件分词后都要匹配

  • or : 条件分词后有一个匹配即可(默认)

  • minmum_should_match : 指定最小匹配的数量

示例:

1.表示name中必须包含张和a

json 复制代码
GET es_db/_doc/_search
{
  "query": {
    "match": {
      "name": {
        "query": "张 a",
        "operator": "and"
      }
    }
  }
}

2.表示name中包含张或者a

json 复制代码
GET es_db/_doc/_search
{
  "query": {
    "match": {
      "name": {
        "query": "张 a",
        "operator": "or"
      }
    }
  }
}

3.至少匹配一个词,minimum_should_match可以跟百分比或者整数

json 复制代码
GET es_db/_doc/_search
{
  "query": {
    "match": {
      "name": {
        "query": "张 a",
        "minimum_should_match": 1
      }
    }
  }
}
json 复制代码
GET es_db/_doc/_search
{
  "query": {
    "match": {
      "name": {
        "query": "张 a",
        "minimum_should_match": "50%"
      }
    }
  
  }

}

1.3 单字段精确匹配

term查询:精确的关键词匹配查询,不会对查询条件进行分词。

示例:

json 复制代码
GET /es_db/_search
{
  "query": {
    "term": {
      "name": {
        "value": "李四"
      }
    }
  }
}

1.4 多字段精确匹配

terms 查询term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件,类似于 mysqlin的用法。

1.5 match_phase

match_phase:会对输入做分词,但是需要结果中也包含所有的分词,而且顺序要求一样。以"hello world"为例,要求结果中必须包含hello和world,而且还要求他们是连着的,顺序也是固定的,hello that word不满足,world hello也不满足条件。

示例:

json 复制代码
GET /es_db/_search
{
  "query": {
     "match_phrase": {
       "remark": "java assistant"
     }
  }
}

1.6 query_string

query_string:和match类似,但是match需要指定字段名,query_string是在所有字段中搜索,范围更广泛。

示例:

1.4 指定字段查询

默认情况下,Elasticsearch 在搜索的结果中,会把文档中保存在_source 的所有字段都返回。如果我们只想获取其中的部分字段,我们可以添加_source 的过滤

示例一:

示例二:

使用includes表示包含哪些字段,使用excludes表示排除哪些字段

1.5 组合查询

组合条件查询是将叶子条件查询语句进行组合而形成的一个完整的查询条件

  • bool : 各条件之间有and,or或not的关系

    • must : 各个条件都必须满足,即各条件是and的关系
    • should : 各个条件有一个满足即可,即各条件是or的关系
    • must_not : 不满足所有条件,即各条件是not的 关系
    • filter : 不计算相关度评分,它不计算_score 即相关度评分,效率更高
  • constant_score : 不计算相关度评分

  • must/filter/shoud/must_not 等的子条件是通过 term/terms/range/ids/exists/match 等叶子条件为参数的

注:以上参数,当只有一个搜索条件时,must等对应的是一个对象,当是多个条件时,对应的是一个数组

示例:

json 复制代码
GET /es_db/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "张三"
          }
        }
      ],
      "should": [
        {
          "match": {
            "name": "李四"
          }
        }
      ]
    }
  }
}

1.6 范围查询

range查询:找出那些落在指定区间内的数字或者时间,range 查询允许以下字符

操作符 说明
gt 大于>
gte 大于等于>=
lt 小于<
lte 小于等于<=

示例:

json 复制代码
GET /es_db/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 10,
        "lte": 40
      }
    }
  }
}

1.6 模糊查询

返回包含与搜索字词相似的字词的文档。

编辑距离是将一个术语转换为另一个术语所需的一个字符更改的次数。这些更改可以包括:

  • 更改字符(box → fox)
  • 删除字符(black → lack)
  • 插入字符(sic → sick)
  • 转置两个相邻字符(act → cat)

为了找到相似的术语,fuzzy 查询会在指定的编辑距离内创建一组搜索词的所有可能的变体或扩展。然后查询返回每个扩展的完全匹配。

通过 fuzziness 修改编辑距离。一般使用默认值 AUTO,根据术语的长度生成编辑距离。

示例:

json 复制代码
GET /es_db/_search
{
  "query": {
    "fuzzy": {
      "remark": {
        "value": "ja",
        "fuzziness": 2
      }
    }
  }
}

1.7 单字段排序

sort排序: 可以让我们按照不同的字段进行排序,并且通过 order 指定排序的方式,desc 降序,asc升序。

示例:

1.8 多个字段排序

假定我们想要结合使用 age 和 _score 进行查询,并且匹配的结果首先按照年龄排序,然后按照相关性得分排序。

示例:

json 复制代码
GET /es_db/_search
{
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    },
    {
      "_score": {
        "order": "desc"
      }
    }
  ]
}

1.9 高亮查询

在进行关键字搜索时,搜索出的内容中的关键字会显示不同的颜色,称之为高亮。

Elasticsearch 可以对查询内容中的关键字部分,进行标签样式(高亮)的设置。

在使用 match 查询的同时,加上一个 highlight 属性:

  • pre_tags :前置标签
  • post_tags:后置标签
  • fields:需要高亮的字段
  • remark:这里声明remark 字段需要高亮,后面可以为这个字段设置特有配置,也可以空

示例:

json 复制代码
GET /es_db/_search
{
  "query": {
    "match": {
      "remark": "java"
    }
  },
  "highlight": {
    "pre_tags": "<font color='red'>",
    "post_tags": "</font>",
    "fields": {
      "remark": {}
    }
  }
}

1.10 分页查询

from:当前页的起始索引,默认从 0 开始。 from = (pageNum - 1) * size

size:每页显示多少条

示例:

json 复制代码
GET /es_db/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": {
        "order": "desc"
      }
    }
  ],
  "from": 0,
  "size": 1
}

DSL查询语言中存在两种:查询DSL(query DSL)过滤DSL(filter DSL)

query DSL 在查询上下文中,查询会回答这个问题------"这个文档匹不匹配这个查询,它的相关度高么?" 如何验证匹配很好理解,如何计算相关度呢?ES中索引的数据都会存储一个 _score分值,分值越高就代表越匹配。另外关于某个搜索的分值计算还是很复杂的,因此也需要一定的时间。

filter DSL 在过滤器上下文中,查询会回答这个问题------"这个文档匹不匹配?" 答案很简单,是或者不是。它不会去计算任何分值,也不会关心返回的排序问题,因此效率会高一点。 过滤上下文是在使用filter参数时候的执行环境,比如在bool查询中使用 must_not或者filter

另外,经常使用过滤器,ES会自动的缓存过滤器的内容,这对于查询来说,会提高很多性能。

json 复制代码
POST /es_db/_doc/_search
{
  "query": {
    "bool": {
      "filter": {
        "term": {
          "age": 25
        }
      }
    }
  }
}

这个查询,它的相关度高么?" 如何验证匹配很好理解,如何计算相关度呢?ES中索引的数据都会存储一个 _score分值,分值越高就代表越匹配。另外关于某个搜索的分值计算还是很复杂的,因此也需要一定的时间。

filter DSL 在过滤器上下文中,查询会回答这个问题------"这个文档匹不匹配?" 答案很简单,是或者不是。它不会去计算任何分值,也不会关心返回的排序问题,因此效率会高一点。 过滤上下文是在使用filter参数时候的执行环境,比如在bool查询中使用 must_not或者filter

另外,经常使用过滤器,ES会自动的缓存过滤器的内容,这对于查询来说,会提高很多性能。

json 复制代码
POST /es_db/_doc/_search
{
  "query": {
    "bool": {
      "filter": {
        "term": {
          "age": 25
        }
      }
    }
  }
}

🌟至此本篇就结束了,下一篇将介绍ES其他高级语法,比如高亮查询、聚合统计分析等

相关推荐
漂流瓶66666635 分钟前
如何搭建spark yarn 模式的集群
大数据·spark·eclipse
啊喜拔牙1 小时前
如何搭建spark yarn模式的集群
大数据·分布式·spark
Elasticsearch2 小时前
Elastic Security 简化了预构建 SIEM 检测规则的自定义
elasticsearch
春风不会绿大地2 小时前
Flink+Hologres搭建实时数仓
大数据·flink
舒一笑3 小时前
一文简单记录打通K8s+Kibana流程如何启动(Windows下的Docker版本)
后端·elasticsearch·kibana
董可伦3 小时前
Flink HA 总结
大数据·flink
不爱学英文的码字机器5 小时前
数字孪生的浪潮:从虚拟镜像到现实世界的 IT 变革
大数据·python
kaamelai5 小时前
Kaamel视角下的MCP安全最佳实践
大数据·人工智能·安全
anqi275 小时前
如何在 IntelliJ IDEA 中编写 Speak 程序
java·大数据·开发语言·spark·intellij-idea
互联科技报6 小时前
孙宇晨将出席迪拜Token2049 与特朗普次子共话加密未来
大数据