ES 复合查询

ES 复合查询

  ES在查询过程中比较多遇到符合查询,既需要多个字段过滤也需要特殊情况处理,本文简单介绍几种查询组合方便快捷查询ES。

bool(组合查询)

  1. must 所有的语句都 必须(must) 匹配,与 AND 、= 等价。
  2. must_not 所有的语句都 不能(must not) 匹配,与 NOT 、!= 等价。
  3. should 至少有一个语句要匹配,与 OR 等价。
   
filter 只过滤符合条件的文档,不计算相关系得分
must 文档必须符合must中所有的条件,会影响相关性得分
must_not 文档必须不符合must_not 中的所有条件
should 文档可以符合should中的条件

 

 

 

 

 

 

它类似于SQL中的WHERE A = 'a' AND B = 'c' OR C = 'c'。一个 bool 过滤器由三部分组成:

{
   "bool" : {
      "must" :     [],
      "should" :   [],
      "must_not" : [],
   }
}

 

布尔查询是一种最常用的组合查询方式,布尔查询把多个子查询组合(combine)成一个布尔表达式,所有子查询之间的逻辑关系是与(and);只有当一个文档满足布尔查询中的所有子查询条件时,ElasticSearch引擎才认为该文档满足查询条件。布尔查询支持的子查询类型共有四种,分别是:must,should,must_not和filter:

查询字句 说明 类型
must 文档必须匹配must查询条件 数组
should 文档应该匹配should子句查询的一个或多个 数组
must_not 文档不能匹配该查询条件 数组
filter 过滤器,文档必须匹配该过滤条件,跟must子句的唯一区别是,filter不影响查询的score 字典
 
 
 
 
 
 

filter查询

  • filter查询只过滤符合条件的文档,es会有只能缓存,因此其执行效率很高,做简单的匹配查询且不考虑算分是,推荐使用filter替代query
上下文类型 执行类型 使用方式
Query 查找和查询语句最匹配的文档,对所有文档进行相关性算分排序 query查询 bool中的must和should
Filter 查找和查询语句匹配的文档 bool中的filter和must_not或者constant_score中的filter

 

 

 

 

should查询

使用分两种情况

bool查询包含should,不包含must查询,只包含should,文档必须满足至少一个条件,minimum_should_match可以满足条件的个数或者百分比。
bool查询同时包含should和must查询,文档不必满足should中的条件,但是如果满足条件,会增加相关性得分(dis_max query/function_score query
/boosting query)。

filter执行原理深度剖析

1.在倒排索引中查找搜索串,获取document list。
2.为每个在倒排索引中搜索到的结果,构建一个bitset,[0, 0, 0, 1, 0, 1]
3.遍历每个过滤条件对应的bitset,优先从最稀疏的开始搜索,查找满足所有条件的document
4.caching bitset,跟踪query,在最近256个query中超过一定次数的过滤条件,缓存其bitset。对于小segment(<1000,或<3%),不缓存bitset。
5.filter大部分情况下来说,在query之前执行,先尽量过滤掉尽可能多的数据
6.如果document有新增或修改,那么cached bitset会被自动更新
7.以后只要是有相同的filter条件的,会直接来使用这个过滤条件对应的cached bitset

 
实例说明:
1.或者并且查询
sql:
select
* from paper where (date="2018-10-11" or uID= 1) and pID!="7ec0e0e5-a4b0-46d7-af56-5b3eab477aea" es: GET blog/paper/_search { "query": { "bool": { "should": [ {"term": {"date":"2018-10-11"}}, {"term": {"uID":1}} ] , "must_not": [ {"term": {"pID": "7ec0e0e5-a4b0-46d7-af56-5b3eab477aea"}} ] } } }

2.并且或者查询

select *from paper where date= "2018-10-11" or(uid=1 and publish= 1)

GET blog/paper/_search
{
  "query": {
    "bool": {
      "should": [
        {"term": {"date": "2018-10-11"}},
        {"bool": {
          "must": [
            {"term": {"uID": "1"}},
            {"term": {"publish": true}}
          ]
        }}
      ]
    }
  }
}

3.搜索java,elasticsearch,hadoop,spark关键字需要至少匹配2个

GET blog/paper/_search
{
  "query": {
    "bool": {
      "should": [
        {"match": {
          "title": "java"
        }},
         {"match": {
          "title": "elasticsearch"
        }},
         {"match": {
          "title": "hadoop"
        }},
         {"match": {
          "title": "spark"
        }}
      ]
      , "minimum_should_match": 2
    }
  }
}

 

range(范围查询)

我们可以用它来查找处于某个范围内的文档。比如我们在商品中查找价格大于 $20 且小于 $40 美元的。

GET /index/type/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 20,
        "lte": 40
      }
    }
  }
}

 

range 查询可同时提供包含(inclusive)和不包含(exclusive)这两种范围表达式,可供组合的选项如下:

  • gt: > 大于(greater than)
  • lt: < 小于(less than)
  • gte: >= 大于或等于(greater than or equal to)
  • lte: <= 小于或等于(less than or equal to)。

range 还可以支持日期范围, 字符串范围类型,特别是在进行日期范围查询时,range还可以支持日期计算。
像这样:

"range" : {
    "timestamp" : {
        "gt" : "now-1h"
    }
}

OR

"range" : {
    "timestamp" : {
        "gt" : "2014-01-01",
        "lt" : "2014-01-01||+1y"
    }
}

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119637.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 网络编程-UDP编程

    网络编程-UDP编程2.UDP端口和TCP端口虽然都使用0~65535,但他们是两套独立的端口,即一个应用程序用TCP占用了端口1234,不影响另一个应用程序用UDP占用端口1234。在Java中使用UDP编程,仍然需要使用Socket,因为应用程序在使用UDP时必须指定网络接口(IP地址)和端口号。1.UDP和TCP编程相比,UDP编程就简单得多,因为UDP没有创建连接,数据包也是一次收发一个,所以没有流的概念。和服务器端相比,客户端使用UDP时,只需要直接向服务器端发送UDP包,然后接收返回的UDP包。…

    2025年10月8日
    5
  • 基于ssm酒店管理系统的毕业设计_酒店管理系统

    基于ssm酒店管理系统的毕业设计_酒店管理系统开发工具(eclipse/idea):eclipse4.5/4.8或者idea2018,jdk1.8数据库:mysql功能模块:登录界面可以选择普通账号登录,酒店管理员登录和系统管理员登录。普通账号注册功能:注册时需填写用户名、密码、姓名、性别、邮箱等个人信息登录功能:登录已经注册过的账号,没注册的无法登录忘记密码功能:登录时忘记密码可通过填写姓名,邮箱查询密码。预订酒店:可以选择预订众多酒店其中的一个酒店的一个房间,可以选择日期住宿管理:可以看到自己是否预订成功,预订成功则有

    2022年9月24日
    1
  • Java开发人员必须掌握的Linux命令(二)[通俗易懂]

    子曰:“工欲善其事,必先利其器。“学习应该是快乐的,在这个乐园中我努力让自己能用简洁易懂(搞笑有趣)的表达来讲解让知识或者技术,让学习之旅充满乐趣,这就是写博文的初心。本篇的旅行地图如下:第一站:小木 会先 登录酷炫的服务器,进入(cd)到神秘的magic 空间(目录),当我们忘记是怎么进入magic空间(目录)时候,可以使用(pwd)立刻得知目前所在的工作目录。第二站:在magi…

    2022年2月28日
    43
  • ps磨皮滤镜portraiture安装教程mac[通俗易懂]

    ps磨皮滤镜portraiture安装教程mac[通俗易懂]PortraitureforMac激活成功教程版是Photoshop上一款支持自动皮肤平滑、愈合和增强效果的磨皮插件,这款portraiture磨皮滤镜主要针对人像进行皮肤修饰、磨皮润色等处理,portraituremac激活成功教程版还可以平滑和去除缺陷,同时保留皮肤纹理和重要的人像细节,功能十分强大,这里为大家带来portraiture激活成功教程版,并附上激活成功教程补丁。portraiture激活成功教程方…

    2022年7月22日
    45
  • cpio制作initrd_正在生成initramfs

    cpio制作initrd_正在生成initramfs1、制作find.|cpio-o-Hnewc|gzip>../rootfs.cpio.gz2、解压zcatrootfs.cpio.gz|cpio-i-d-Hnewc–no-absolute-filename3、内核逻辑编译内核的时候会有一个GENinitramfs_data.cpio.gz如果有文件,就编译

    2022年8月11日
    11
  • Java 数据库image型输出图片

    有一些程序在sqlserver中存储图片的方式是通过二进制存储导数据库的,那么保存进去之后,怎么把图片显示出来呢?直接上代码,servlet后台代码:byte[]b1=””;//数据库查询出来的二进制InputStreamin=newByteArrayInputStream(b1);response.setContentType(“image/jpg”);Outpu…

    2022年4月15日
    46

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号