【ElasticSearch系列-03】ElasticSearch的高级句法查询Query DSL

news2024/11/24 5:45:33

ElasticSearch系列整体栏目


内容链接地址
【一】ElasticSearch下载和安装https://zhenghuisheng.blog.csdn.net/article/details/129260827
【二】ElasticSearch概念和基本操作https://blog.csdn.net/zhenghuishengq/article/details/134121631
【二】ElasticSearch的高级查询Query DSLhttps://blog.csdn.net/zhenghuishengq/article/details/134159587

ElasticSearch的高级句法查询Query DSL

  • 一,ElasticSearch高级查询语法Query DSL
    • 一,Query DSL的基本使用
      • 1.1,深分页查询Scroll
      • 1.2,match条件查询
      • 1.3,match_phrase短语查询
      • 1.4,multi_match多字段查询
      • 1.5,query_string 查询
      • 1.6,term精确匹配
      • 1.7,prefix前缀查询
      • 1.8,通配符查询wildcard
      • 1.9,范围查询range
      • 1.10,fuzzy模糊查询
      • 1.11,highlight查询
    • 2,Query DSL多条件查询(高级查询)
      • 2.1,Bool Query布尔查询
      • 2.2,Boosting Query权重查询
      • 2.3,Dis max query 最佳匹配
      • 2.4,Cross Field跨字段匹配

一,ElasticSearch高级查询语法Query DSL

前面两篇主要讲解了es的安装以及一些基本的概念,接下来这篇讲解的是es的高阶语法,QueryDSL。在这里主要是用ik分词器讲解,暂不使用默认的分词器。

一,Query DSL的基本使用

在安装了kibana之后,内部会有一个search的语句,用来查询数据

GET _search
{
  "query": {
    "match_all": {}
  }
}

其结果如下,默认是返回前10条数据,类似于做了分页,默认加了一个from0和一个size10,并且在es中,size默认是小于或者等于10000,如果超过这个值,就会直接抛异常

在这里插入图片描述

1.1,深分页查询Scroll

上面说了默认采用的是from加size的方式来解决分页数据返回的问题,但是size的数据是有大小的限制的,当然也可以通过以下命令来调节size的大小

PUT /zhs/_settings
{ 
  "index.max_result_window" :"20000"
}

虽然这种方式可以暂时调节size大小,但是治标不治本,因为依旧是会存在限制,并且由于数据量太大,还可能将内存撑爆。因此后面引入了这种Scroll游标的方式来查询全量数据

GET /zhs_db/_search?scroll=1m   //1m表示查询时间窗口保持1分钟
{
  "query": {"match_all": {}},
  "size": 10		//批量查询10条数据
}

在将查询的值返回中可以看出,会生成一个_scroll_id,以及返回一些分片数,查询的总条数等

在这里插入图片描述

就是比如说第一次查询10条数据,随后记录最后一条数据的id,然后在这个时间窗口期内,携带这个id再去库中拉取后十条数据,往复如此。不管是关系系数据库还是非关系型数据库,其设计思想都是这样

拉取的数据会存储在快照里面,后面的操作都是操作这个快照中缓存的数据。因此为了保证性能问题,会牺牲一些精准度,因为后面写进来的数据不在这个快照里面。

1.2,match条件查询

在使用这个match之前,先创建一个索引,并设置分词器为ik分词器

DELETE /zhs_db
PUT /zhs_db		
{
  "settings" : {
      "index" : {
          "analysis.analyzer.default.type": "ik_max_word"
      }
  }
}

先插入几条数据,先用最基础的Put的方式插入五条数据


PUT /zhs_db/_doc/1
{
"address":"东岳泰山"
}
PUT /zhs_db/_doc/2
{
"address":"西岳华山"
}
PUT /zhs_db/_doc/3
{
"address":"南岳衡山"
}
PUT /zhs_db/_doc/4
{
"address":"北岳恒山"
}
PUT /zhs_db/_doc/5
{
"address":"中岳嵩山"
}

在确定要查询某一条数据时,可以先通过这个分词分析看看是如何进行分词的

POST _analyze
{
  "analyzer": "ik_max_word",
  "text": "中岳嵩山"
}

那么可以直接通过这个match的方式批量查询数据

GET /zhs_db/_search
{
  "query": {
    "match": {
      "address": "中岳"
    }
  }
}

如果是要查询特定的某个值,可以直接再加一个operator属性,并且value设置成and,如果没有设置这个属性,那么默认值就是的or

GET /zhs_db/_search
{
  "query": {
    "match": {
      "address": {
        "query": "中岳嵩山",
        "operator": "and"
      }
    }
  }
}

除了上面的operator之外,还可以使用 minimum_should_match ,用于最小分词匹配。就是说分词器默认分为中岳和嵩山两个,只需要满足其中一个就能被查出来

address:{
    "query":"中岳嵩山""minimum_should_match": 1
}

1.3,match_phrase短语查询

在使用这个短语查询时,需要通过分词器分析,判断两个词的下标是否连续

GET /zhs_db/_search
{
  "query": {
    "match_phrase": {
      "address": "中岳嵩山"
    }
  }
}

如通过这个ik分词器分析,可以得知这两个分开的词的position是连续的,分别为0和1,如果不连续,则不能将值查询出

在这里插入图片描述

当然为了解决这个间隔问题,可以直接通过设置 slop 属性来设置允许多少个空格进行匹配

address:{
    "query":"中岳嵩山""slop": 1
}

1.4,multi_match多字段查询

上面主要讲解的是单字段查询,但是在实际开发中一般都是多字段查询,其语句如下

GET /zhs_db/_search
{
  "query": {
    "multi_match": {
      "query": "中岳嵩山",
      "fields": ["address","name"]
    }
  }
}

1.5,query_string 查询

queryString相当于是一个multi_match的一个综合版,如果没有指定具体的字段,则会在全字段中查询

GET /zhs_db/_search
{
  "query": {
    "query_string": {
      "query": "中岳"
    }
  }
}

可以设置默认的字段,也可以指定多个字段

"query_string": {
  //"default_field": "address",
  "fields": ["name","address"],
  "query": "中岳"
}

1.6,term精确匹配

上面的match属于是模糊匹配,而使用精确匹配的,就是这个term。

在ES的Mapping Type 中 keyword , date ,integer, long , double , boolean or ip 这些类型不分词,只有text类型分词。因此term在对这些数据进行查询时,就是精确匹配

GET /zhs_db/_search
{
  "query": {
    "term": {
      "address": "中岳"
    }
  }
}

如果想要对全字段进行精确匹配,可以添加一个keyword 关键字

"address.keyword": "中岳嵩山"

在es中,查询会有算分操作,而算分操作会影响到性能问题,而精确匹配是不需要算分的,可以将query转成filter,从而忽略算分所带来的影响

"query":{
    "constant_score":{
        "filter":{
            
        }
    }
}

如果短时间内存在多次term的查询,那么就会将这部分数据缓存起来

1.7,prefix前缀查询

前缀查询就是查询以某个字段开头的数据,因此用不上底层的倒排字典,而是将所有的数据遍历一遍,将符合的数据返回。由于用不上倒排索引,因此对性能是有一定的影响的

PUT /zhs_db/_search
{
    "query":{
        "prefix":{
            "address":{
                "value":"嵩山"
            }
        }
    }
}

1.8,通配符查询wildcard

通配符查询就和这个前缀查询一样,都是利用不上这个倒排索引,而是将所有的数据遍历查询一遍,符合的数据返回。

GET /zhs_db/_search
{
  "query": {
    "wildcard": {
      "address": {
        "value": "*山*"
      }
    }
  }
}

1.9,范围查询range

可以直接通过这个range关键字实现范围查询,

  • gte 大于等于
  • lte 小于等于
  • gt 大于
  • lt 小于
  • now 当前时间
POST /zhs_db/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 25,
        "lte": 28
      }
    }
  }
}

1.10,fuzzy模糊查询

fuzzy表示允许在打错字的情况下,将想要查询的数据查询出来。

GET /zhs_db/_search
{
  "query": {
    "fuzzy": {
      "address": {
        "value": "松山",
        "fuzziness": 1    //表示允许错一个字
      }
    }
  }
}

除了使用上面这种方式,还能用match的方式实现这种错别字的模糊查询

GET /zhs_db/_search
{
  "query": {
    "match": {
      "address": {
        "query": "松山",
        "fuzziness": 1
      }
    }
  }
}

1.11,highlight查询

就是将query查询出来的结果,通过highlight的方式实现高亮

GET /products/_search
{
  "query": {
    "term": {
      "name": {
        "value": "牛仔"
      }
    }
  },
  "highlight": {
    "fields": {
      "*":{}
    }
  }
}

2,Query DSL多条件查询(高级查询)

2.1,Bool Query布尔查询

在一个bool查询中,可以是一个或者多个查询字句的组合,字句总共有四种,分别是 must、should、must_not、filter,前两者使用时内部会进行算分的操作,后二者不会

must相当于是and操作,即所有几句中的查询条件都要满足。如下must中是一个数组,每个子查询中就是一个正常的query dsl查询,如必须满足中地址字段中带有公园,remark字段中带有北的数据

GET /zhs_db/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "address": "公园"
          }
        },
        {
          "match": {
            "remark": "北"
          }
        }
      ]
    }
  }
}

shouuld 表示的就是一个or的应用,表示只需要满足其中的一个查询字句就能将结果返回

GET /zhs_db/_search
{
  "query": {
    "bool": {
      "should": []
    }
  }
}

2.2,Boosting Query权重查询

权重查询是一种控制手段,通过设置boost权重的值来影响最终的查询结果,权重的设置如下

  • 当设置的boost大于1时,查询的的相关性会提高
  • 当设置的boost大于0而小于1时,查询的相关性会降低
  • 当设置的boost的值为负数时,贡献负分

举一个例子,查询一篇文章时,将会员的文章显示在普通用户文章的前面,如下面的代码,先创建一个文章索引,随后插入两条数据,一条是vip用户的,一条是普通用户的,文章标题一样

PUT /article_db
POST /article_db/_bulk
{"index": {"_id": "1"}}
{"title":"java入门","comment":"精通java","type":"vip"}
{"index": {"_id": "2"}}
{"title":"java入门","comment":"精通java","type":"ordinary"}

那么在查询时,想将vip用户的文章排在前面,就可以直接通过设置这个boost权重进行设置,将vip用户的权重值设置为大于1,这样在算分时,算的分值就更大

GET /article_db/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "java入门"
          }
        },
        {
          "match": {
            "type": {
              "query": "vip",
              "boost": 3
            }
          }
        },
        {
          "match": {
            "type": {
              "query": "ordinary",
              "boost": 1
            }
          }
        }
      ]
    }
  }
}

如下图所示,vip的算分为2.6,而普通用户的算分在1.2。如果算分值一样,谁id小谁在前面

在这里插入图片描述

当然如果查询出了不需要的数据,优先考虑通过过滤去掉数据,再考虑降低其权重

2.3,Dis max query 最佳匹配

通过dis_max以及结合queries进行使用,并且可以通过设置这个tie_breaker来确人是最佳匹配,还是所有的字段的值同等重要

POST /article_db/_search
{
    "query": {
        "dis_max": {
            "queries": [
                { "match": { "title": "java" }},
                { "match": { "comment":  "java" }}
            ],
            "tie_breaker": 0.5	//0代表使用最佳匹配;1代表所有语句同等重要。
        }
    }
}

但是在实际开发中,更加的推荐通过这个multi_match这个方式来实现这个最佳字段匹配,并且设置这个type类型为 best_fields

POST /article_db/_search
{
  "query": {
    "multi_match": {
      "type": "best_fields",
      "query": "java",
      "fields": ["title","comment"],
      "tie_breaker": 0.2	//0代表使用最佳匹配;1代表所有语句同等重要。
    }
  }
}

除了实现最佳匹配之外,multi_match还实现了最多字段匹配,就是将type的类型设置成 most_fields

GET /titles/_search
{
  "query": {
    "multi_match": {
      "query": "java,
      "type": "most_fields",
      "fields": [
        "title",
        "comment"
      ]
    }
  }
}

2.4,Cross Field跨字段匹配

如在遇到某些场景,需要结合多个字段的值进行匹配,如省市区,在上面讲了一种copy_to的方式解决这种跨字段匹配的方式,也可以使用这个 Cross Field 实现多字段匹配

如先创建一个address_db的地址索引,随后批量的插入一些数据

PUT /address_db
PUT /address_db/_bulk
{ "index": { "_id": "1"} }
{"province": "广东","city": "深圳","region":"南山"}
{ "index": { "_id": "2"} }
{"province": "广东","city": "深圳","region":"福田"}
{ "index": { "_id": "3"} }
{"province": "广东","city": "深圳","region":"宝安"}
{ "index": { "_id": "4"} }
{"province": "广东","city": "深圳","region":"龙岗"}
}

随后通过这个multi_match多字段查询,并且设置type类型为 cross_fields

GET /address_db/_search
{
  "query": {
    "multi_match": {
      "query": "广东深圳宝安",
      "type": "cross_fields",
      "operator": "and", 
      "fields": ["province","city","region"]
    }
  }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1161870.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

酷开系统丨酷开会员,让你畅享无限的娱乐乐趣

你是否厌倦一成不变的平凡生活,渴望寻找一些刺激和乐趣?那么,让我们一起走进酷开会员的世界,那里充满了无限的可能性和无尽的乐趣!酷开系统为会员群体精心打造的娱乐平台,汇聚了众多热门影视、音乐、游戏直…

【功能更新】JVS源码级低代码:列表页组件、标签栏、多流程等等

在数字化时代,低代码平台已经成为企业快速搭建应用、提升开发效率的首选工具。为了满足广大用户不断增长的需求,我们持续努力,对JVS低代码平台进行了一系列重要的更新和优化。本次更新如下: 新增: 1、表单中新增列表…

lua-web-utils库

lua--导入所需的库local web_utilsrequire("lua-web-utils")--定义要下载的URLlocal url"https://jshk.com.cn/"--定义代理服务器的主机名和端口号local proxy_port8000--使用web_utils的download函数下载URLlocal file_pathweb_utils.download(url,proxy_…

【通关选择】upload-labs通关攻略(全)

前提条件: 1.文件能够成功上传到服务器 2.攻击者能够知道文件的上传路径 upload-labs靶场 Pass-01( 前端验证) 三种方法解决思路 1.禁用客户端JavaScript弹窗 2.通过burp抓包,修改后缀名 3.f12删除return filecheck&#xff0…

uniapp原生插件之安卓原生插件集

插件介绍 安卓原生插件集,集成了常用的插件,包括设备,语音、文件、屏幕、usb、TCP等等 插件地址 安卓原生插件集 - DCloud 插件市场 超级福利 uniapp 插件购买超级福利 详细使用文档 使用文档 插件集成内容 腾讯Bugly插件汉字转…

【C/C++】仿函数

函数调用运算符 () 也可以重载由于重载后使用的方式非常像函数的调用&#xff0c;因此称为仿函数仿函数没有固定写法&#xff0c;非常灵活 示例&#xff1a; #include <iostream> #include <string> using namespace std;class MyPrint { public://重载的运算符是…

Redis安装Linux

1、下载安装包 wget http://download.redis.io/releases/redis-3.0.0.tar.gz 2、安装 mkdir /usr/local/redis cp redis-3.0.0.tar.gz /usr/local/redis cd /usr/local/redis tar -zxvf redis-3.0.0.tar.gz cd /usr/local/redis/redis-3.0.0 make PREFIX/usr/local/red…

为什么大家更看好定制开发型CRM

相比传统CRM软件&#xff0c;定制开发型CRM受到了越来越多企业的青睐。为什么大家更看好定制开发类型而不是发挥更加稳定的传统CRM&#xff1f;选择定制型CRM软件主要有以下几个理由&#xff1a; 一、自选功能性价比更高 定制型软件可以选择性的购买功能模块&#xff0c;确保…

算法专栏 ---- trie树,并查集

trie树 #include <iostream> using namespace std; const int N 1000010; int son[N][26],cnt[N],idx; //明确前面两个数组以及idx的含义 //我们把son这个二维数组看成一个字典树 //本题要求26个字母&#xff0c;所以我们每个节点里面最多有26个儿子节点 //而我们本题要…

DL4J无法下载MNIST数据集解决 Server returned HTTP response code: 403 for URL解决方法

报错情况 报错如下&#xff1a; 16:45:41.463 [main] INFO org.nd4j.nativeblas.Nd4jBlas - Number of threads used for OpenMP BLAS: 6 16:45:41.497 [main] INFO org.nd4j.linalg.api.ops.executioner.DefaultOpExecutioner - Backend used: [CPU]; OS: [Windows 10] 16:4…

Sqlserver2012和Sqlserver2019数据库设置最大并行数解决数据库CPU高问题

请注意&#xff0c;最大并行数范围是0到CPU的实际逻辑核心数的最大值 SQL Server2019之前的版本&#xff0c;最大并行度默认值都是0&#xff0c;也就是无限制。SQL Server2019最大并行度默认值会根据CPU逻辑处理器数自动计算&#xff0c;如数值是8&#xff0c;那么也就是一个执…

时序预测 | Python实现ARIMA-CNN-LSTM差分自回归移动平均模型结合卷积长短期记忆神经网络时间序列预测

时序预测 | Python实现ARIMA-CNN-LSTM差分自回归移动平均模型结合卷积长短期记忆神经网络时间序列预测 目录 时序预测 | Python实现ARIMA-CNN-LSTM差分自回归移动平均模型结合卷积长短期记忆神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 时序预测 …

第23期 | GPTSecurity周报

GPTSecurity是一个涵盖了前沿学术研究和实践经验分享的社区&#xff0c;集成了生成预训练 Transformer&#xff08;GPT&#xff09;、人工智能生成内容&#xff08;AIGC&#xff09;以及大型语言模型&#xff08;LLM&#xff09;等安全领域应用的知识。在这里&#xff0c;您可以…

Django开发使用DRF框架之创建纯净版框架步骤

使用Django开发时&#xff0c;遇到前后端分离的项目&#xff0c;需要创建一个纯净版的Django框架&#xff0c;在使用restframework框架时&#xff0c;有些Django自带的功能或者说是APP用不到&#xff0c;那需要怎么设置呢&#xff0c;需要解决哪些问题&#xff0c;请见下面的详…

《研发效能(DevOps)工程师》课程简介(三)丨IDCF

在研发效能领域中&#xff0c;【开发与交付】的学习重点在于掌握高效的开发工具和框架&#xff0c;了解敏捷开发方法&#xff0c;掌握持续集成与持续交付技术&#xff0c;以及如何保证应用程序的安全性和合规性等方面。 由国家工业和信息化部教育与考试中心颁发的职业技术证书…

【虹科干货】Redis企业版给DevOps团队带来了哪些价值?

内存太贵&#xff1f;现代化转型太难&#xff1f;还在花费精力维护数据库基础设施&#xff1f;Redis Enterprise 在开源版的基础上增加了一整套包含管理、自动化、弹性以及安全等方面的功能&#xff0c;使其更适合企业级的应用场景。那么&#xff0c;Redis Enterprise 如何能成…

防近视台灯有必要买吗?分享能够预防近视的专业护眼台灯

对于护眼台灯能够预防近视这件事&#xff0c;很多家长认为这是一种智商税的。其实不然&#xff0c;护眼台灯之所以能够预防近视&#xff0c;当然不是说只要使用了这种台灯&#xff0c;就真的不会近视了。首先我们要明白&#xff0c;台灯对于孩子而言是夜晚阅读书写时必不可少的…

nacos1.1.4 持久化数据库升级到 Mysql8.0.34

1 环境要求 CentOS 7、MySQL 8.0.34 2 安装步骤 2.1 docker拉取mysql 8.0.34命令 这样写时拉取最新版本&#xff0c;可以直接写到对应的版本 docker pull mysql:8.0docker pull mysql:8.0.342.2 docker images确认 2.3 安装运行mysql8.0容器 docker run -p 3307:3306 --n…

API文档自动生成

API文档自动生成 背景smart-doc配置效果图 背景 对于API接口文档自动生成&#xff0c;可能大家&#xff0c;最新想到的是用swagger&#xff0c;但是有以下问题&#xff1a; 对代码侵入太强版本升级&#xff0c;并不兼容不能生成各种类型的文档 所以&#xff0c;今天给大家推荐…

Java算法:二分查找

一、 二分查找注意 前提是数组必须是有序的&#xff0c;否则无法正常工作。如果数组不是有序的&#xff0c;需要先对数组进行排序&#xff0c;然后才能使用二分查找算法。 二、二分查找高效算法 二分查找也称为折半查找&#xff0c;是一种在有序数组中查找目标元素的算法。它的…