ElasticSearch查询笔记目录

  涉及的常用查询内容较多,将分多个章节进行笔记整理,具体如下:

  1. ElasticSearch查询学习笔记章节1——term,terms,match,id查询

   主要是依据精准的查询条件来查询,查询速度快,也是最常用的几类查询方式,具体种类如下:

  • term查询
  • terms查询
  • match_all查询
  • match查询
  • 布尔match查询
  • multi_match查询
  • 根据文档id查询(单个id)
  • 根据文档ids查询(多个id)
  1. ElasticSearch查询学习笔记章节2——prefix,fuzzy,wildcard,range,regexp查询

  主要是涉及ElasticSearch查询条件相对模糊,查询速度相对慢,实时查询时应尽量避免这些方式,但是这些查询方式又具有自己独特不可代替的功能,还是还有必要,具体如下:

  • prefix查询
  • fuzzy查询
  • wildcard查询
  • range查询
  • regexp查询
  1. ElasticSearch查询学习笔记章节3——scroll,delete-by-query,bool,boosting,filter,highlight查询

  主要涉及ElasticSearch的一些常用的杂项查询;

  • 深分页scroll查询
  • delete-by-query
  • bool查询
  • boosting查询
  • filter查询
  • highlight(高亮)查询
  1. ElasticSearch查询学习笔记章节4——cardinality,range,extended_stats聚合统计aggregations查询

  主要涉及ES的聚合查询Aggregations;

  • cardinality(去重计数)查询
  • range(范围统计)查询
  • extended_stats(统计聚合)查询
  1. ElasticSearch查询学习笔记章节5——geo_distance,geo_bounding_box,geo_polygon地图检索geo查询

.   主要涉及ES的地图检索geo相关的查询;

  • geo_distance查询
  • geo_bounding_box查询
  • geo_polygon查询

整体Java代码的测试用例项目

  整个章节的Java代码放在CSDN资源ElasticSearch常用查询的Java实现;路径效果如下图,欢迎下载访问;在这里插入图片描述

前 言

  ElasticSearch(以下简称:ES)作为搜索引擎,那么她最核心的重点当然是查询,接下来就给大家整理下ES的一些常用的搜索实现,本笔记主要实现RESTFul风格的代码和Java API代码为主,至于更多的其它API,可参考官网的各类API来实现;
  官网各类编程语言API:Elasticsearch Clients
在这里插入图片描述

图1 ES官网常用的各类编程语言API

ElasticSearch的版本

  本人使用的ES版本是7.7.1,已经去除了type的概念。

ElasticSearch测试的索引及数据准备

索引要求

索引名称:sms-logs-index

字段名称备注ES数据类型
createDate创建时间date
senDate发送时间date
longCode发送的长号码,如“102365024”keyword
moblie手机号码,如“13526544896”keyword
corpName发送公司名称,需要分词检索text(ik分词器)
smsContent发送短信内容,需要分词检索text(ik分词器)
state短信下发状态 1 成功 0 失败integer
opratorId运营商编号 1移动 2 联通 3电信integer
province省份keyword
ipAddr下发的服务器地址keyword
replyTotal短信状态报告返回时长(秒)integer
fee扣费integer

  这里创建测试索引和添加测试数据我就偷懒以下,就直接用RESTFul代码实现,就不用Java了,如果对Java版本创建索引和添加数据有疑问的,可以参考博客ElasticSearch数据结构和基本操作;

RESTful操作新建索引

PUT /sms-logs-index
{
  "settings":
  {
    "number_of_replicas": 3
    , "number_of_shards": 5
  }
  , "mappings": 
  {
    "properties": 
    {
      "createDate":
      {
        "type": "date"
       ,"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
      }
      ,"senDate":
      {
        "type": "date"
       ,"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
      }
      ,"longCode":
      {
        "type": "keyword"
      }
      ,"moblie":
      {
        "type": "keyword"
      }
      ,"corpName":
      {
        "type": "text"
       ,"analyzer": "ik_smart"
      }
      ,"smsContent":
      {
         "type": "text" 
        ,"analyzer": "ik_smart"
      }
      ,"state":
      {
        "type": "integer"
      }
      ,"opratorId":
      {
        "type": "integer"
      }
      ,"province":
      {
        "type": "keyword"
      }
      ,"ipAddr":
      {
        "type": "keyword"
      }
      ,"replyTotal":
      {
        "type": "integer"
      }
      ,"fee":
      {
        "type": "double"
      }
    }
  }
}

RESTful操作添加测试数据

PUT /sms-logs-index/_doc/1
{

"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"10201021"
,"moblie":13026254898
,"corpName":"上海智慧软件有限公司"
,"smsContent":"连接你我,智慧软件,让生活更美好"
,"state":"1"
,"opratorId":"1"
,"province":"上海"
,"ipAddr":"10.215.19.45"
,"replyTotal":"1"
,"fee":"0.1"
}

PUT /sms-logs-index/_doc/2
{

"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"20165411010"
,"moblie":15248754897
,"corpName":"北京鑫鑫能源有限公司"
,"smsContent":"欢迎使用新能源,让世界更环保"
,"state":"1"
,"opratorId":"2"
,"province":"北京"
,"ipAddr":"10.245.29.280"
,"replyTotal":"0.6"
,"fee":"0.5"
}

PUT /sms-logs-index/_doc/3
{

"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"5478434123"
,"moblie":18056587445
,"corpName":"中威集团"
,"smsContent":"中威集团,服务于你的身边!"
,"state":"0"
,"opratorId":"3"
,"province":"杭州"
,"ipAddr":"10.248.19.45"
,"replyTotal":"4"
,"fee":"20"
}

PUT /sms-logs-index/_doc/4
{

"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"87454120"
,"moblie":13625789645
,"corpName":"爱美化妆品有限公司"
,"smsContent":"魅力,势不可挡,爱美爱美"
,"state":"1"
,"opratorId":"1"
,"province":"上海"
,"ipAddr":"10.258.19.45"
,"replyTotal":"1"
,"fee":"200"
}

PUT /sms-logs-index/_doc/5
{

"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"24514635"
,"moblie":18545427895
,"corpName":"东东集团"
,"smsContent":"数据驱动,AI推动,新零售模型让你的购买更心怡!"
,"state":"1"
,"opratorId":"1"
,"province":"北京"
,"ipAddr":"10.254.19.45"
,"replyTotal":"1"
,"fee":"6000"
}

PUT /sms-logs-index/_doc/6
{

"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"89451254"
,"moblie":13028457893
,"corpName":"大兴建筑有限公司"
,"smsContent":"我房建,你放心,大兴建筑!"
,"state":"1"
,"opratorId":"1"
,"province":"杭州"
,"ipAddr":"10.215.19.45"
,"replyTotal":"1"
,"fee":"500"
}

PUT /sms-logs-index/_doc/7
{

"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"33656412674"
,"moblie":18956451203
,"corpName":"华丽网集团"
,"smsContent":"网络安全,华丽靠谱!"
,"state":"1"
,"opratorId":"3"
,"province":"上海"
,"ipAddr":"10.215.254.45"
,"replyTotal":"1"
,"fee":"2000"
}

PUT /sms-logs-index/_doc/8
{

"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"56412345"
,"moblie":17055452369
,"corpName":"万事Ok公司"
,"smsContent":"万事Ok,找我没错!"
,"state":"0"
,"opratorId":"2"
,"province":"杭州"
,"ipAddr":"10.215.19.45"
,"replyTotal":"1"
,"fee":"200"
}

PUT /sms-logs-index/_doc/9
{

"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"5784320"
,"moblie":15236964578
,"corpName":"花花派"
,"smsContent":"花开花落,魅力女性,买花选我!"
,"state":"1"
,"opratorId":"1"
,"province":"上海"
,"ipAddr":"10.265.19.45"
,"replyTotal":"1"
,"fee":"0.1"
}

PUT /sms-logs-index/_doc/10
{

"createDate":"2020-09-16"
,"senDate":"2020-09-16"
,"longCode":"54784641"
,"moblie":15625584654
,"corpName":"勾股科技有限公司"
,"smsContent":"智能算法,智慧生活,勾股科技!"
,"state":"1"
,"opratorId":"2"
,"province":"杭州"
,"ipAddr":"10.215.19.45"
,"replyTotal":"6"
,"fee":"4000"
}

PUT /sms-logs-index/_doc/11
{

"createDate":"2020-09-22"
,"senDate":"2020-09-22"
,"longCode":"458744536"
,"moblie":134625584654
,"corpName":"星雨文化传媒"
,"smsContent":"魅力宣传,星雨传媒!"
,"state":"1"
,"opratorId":"3"
,"province":"杭州"
,"ipAddr":"10.289.19.45"
,"replyTotal":"6"
,"fee":"500"
}

PUT /sms-logs-index/_doc/12
{

"createDate":"2020-09-22"
,"senDate":"2020-09-22"
,"longCode":"123546241"
,"moblie":156625584654
,"corpName":"哈雷天文用具公司"
,"smsContent":"天文研究,放心推动,哈雷天文!"
,"state":"1"
,"opratorId":"3"
,"province":"杭州"
,"ipAddr":"10.289.19.45"
,"replyTotal":"6"
,"fee":"500"
}

ElasticSearch常用查询原理及实现

  本人采用采用IDE编辑Java代码,用到的maven依赖文件pom.xml如下;

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>SparkOnHiveToEs_v1</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>SparkOnHiveToEs_v1</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.elasticsearch/elasticsearch -->
    <!--ES本身的依赖-->
    <dependency>
      <groupId>org.elasticsearch</groupId>
      <artifactId>elasticsearch</artifactId>
      <version>7.7.1</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.elasticsearch.client/elasticsearch-rest-high-level-client -->
    <!--ES高级API,用来连接ES的Client等操作-->
    <dependency>
      <groupId>org.elasticsearch.client</groupId>
      <artifactId>elasticsearch-rest-high-level-client</artifactId>
      <version>7.7.1</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <!--junit,Test测试使用-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>


    <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
    <!--lombok ,用来自动生成对象类的构造函数,get,set属性等-->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.12</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.testng</groupId>
      <artifactId>testng</artifactId>
      <version>RELEASE</version>
      <scope>compile</scope>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <!--jackson,用来封装json-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.11.0</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.elasticsearch/elasticsearch-spark-20 -->
    <dependency>
      <groupId>org.elasticsearch</groupId>
      <artifactId>elasticsearch-spark-20_2.11</artifactId>
      <version>7.7.1</version>
    </dependency>


    <!-- https://mvnrepository.com/artifact/org.apache.spark/spark-core -->
    <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-core_2.11</artifactId>
      <version>2.3.3</version>
    </dependency>

    <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-sql_2.11</artifactId>
      <version>2.3.3</version>
    </dependency>

    <dependency>
      <groupId>org.apache.spark</groupId>
      <artifactId>spark-hive_2.11</artifactId>
      <version>2.3.3</version>
      <scope>compile</scope>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>compile</scope>
    </dependency>

    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.9.1</version>
    </dependency>

    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
      <version>2.9.1</version>
    </dependency>
  </dependencies>


  <build>
    <plugins>
      <!-- 在maven项目中既有java又有scala代码时配置 maven-scala-plugin 插件打包时可以将两类代码一起打包 -->
      <plugin>
        <groupId>org.scala-tools</groupId>
        <artifactId>maven-scala-plugin</artifactId>
        <version>2.15.2</version>
        <executions>
          <execution>
            <goals>
              <goal>compile</goal>
              <goal>testCompile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>

      <!-- maven 打jar包需要插件 -->
      <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.4</version>
        <configuration>
          <!-- 设置false后是去掉 MySpark-1.0-SNAPSHOT-jar-with-dependencies.jar 后的 “-jar-with-dependencies” -->
          <!--<appendAssemblyId>false</appendAssemblyId>-->
          <descriptorRefs>
            <descriptorRef>jar-with-dependencies</descriptorRef>
          </descriptorRefs>
          <archive>
            <manifest>
              <mainClass>com.bjsxt.scalaspark.core.examples.ExecuteLinuxShell</mainClass>
            </manifest>
          </archive>
        </configuration>
        <executions>
          <execution>

            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
              <goal>assembly</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
</project>

  一样的,先实现连接ES的client类和方法;

package cn.focusmedia.esapp.feign;

import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;

@Slf4j
public class EsClient
{
    public static RestHighLevelClient getClient()
    {
        //配置集群连接的IP和端口,正式项目是要走配置文件的,这里偷懒下,就写死吧,也方便说明问题,不要骂我代码太烂就行
        //创建HttpHost对象
        HttpHost[] myHttpHost = new HttpHost[7];
        myHttpHost[0]=new HttpHost("10.219.10.11",9200);
        myHttpHost[1]=new HttpHost("10.219.10.12",9200);
        myHttpHost[2]=new HttpHost("10.219.10.13",9200);
        myHttpHost[3]=new HttpHost("10.219.10.14",9200);
        myHttpHost[4]=new HttpHost("10.219.10.15",9200);
        myHttpHost[5]=new HttpHost("10.219.10.16",9200);
        myHttpHost[6]=new HttpHost("10.219.10.17",9200);

        //创建RestClientBuilder对象
        RestClientBuilder myRestClientBuilder=RestClient.builder(myHttpHost);

        //创建RestHighLevelClient对象
        RestHighLevelClient myclient=new RestHighLevelClient(myRestClientBuilder);

        log.info("RestClientUtil intfo create rest high level client successful!");

        return myclient;
    }
}

  万事具备,开始正式进入主题,关于ES的常用查询的笔记如下;
  注意:第一个查询例子本人会贴图查看RESTFul代码及Java代码的查询结果,详细说明结果字段的含义,后续的查询本人只提供两种API的样例代码,不再贴出查询结果,希望读者自行实验以下,举一反三,至于RESTFul代码和Java代码,都是本人分别在Kibana和IDE上测试实现过的,基本不会有啥bug,如果有不足,请大家留言指出,大家一起探讨下。

term查询

term的查询是代表完全匹配,搜索之前不会对你搜索的关键字进行分词,如关键字手机,不会分成手和机;再根据关键字去文档分词库中去匹配内容。
类似于MySQL库的 where province = ?

  实现要求,依据province字段查询所有北京公司的短信内容

  RESTFUL代码如下;

# from size类似于musql的limit
POST /sms-logs-index/_search
{
  "from": 0       
  ,"size": 10
  , "query": {
    "term": {
      "province": {
        "value": "北京"
      }
    }
  }
}

  RESTFUL查询结果代码如下图2;
在这里插入图片描述

图2 term查询的RESTFUL代码查询结果

  Java代码如下;

    static RestHighLevelClient myClient= EsClient.getClient();  //获取操作ES的
    String index="sms-logs-index";
    
    @Test
    public void termsQuery() throws IOException {
        //1。创建request对象,查询用的对象一般都是SearchRequest对象
        SearchRequest mySearchRequest = new SearchRequest(index);

        //2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.from(0).size(10).query(QueryBuilders.termsQuery("province", "北京", "上海", "杭州")); //指定term查新条件

        mySearchRequest.source(builder);
        //3. 执行查询
        SearchResponse search = myClient.search(mySearchRequest, RequestOptions.DEFAULT);

        //4. 获取到_source中的数据,并展示
        //注意RESTFUL风格上是两个hits,所以这里要两次getHits()
        for (SearchHit hit : search.getHits().getHits()) {
            Map<String, Object> result = hit.getSourceAsMap();
            System.out.println(result);
        }
    }

  Java代码如下;
在这里插入图片描述

图3 term查询的Java代码查询结果

terms查询

terms和terms的查询机制是一样的,都不会将指定的查询关键字进行分词,直接去分词库中匹配,找到相应的文档内容。
terms:是针对一个字段包含多个值时使用。
换句话说:
term类似于MySQL的 where province=?
terms类似于MySQL中的 where province in (?, ? ,?)

  注意:term和terms只是说不会对关键字进行分词,并不是说只能用于keyword类型的字段查询,如假设文档中有个字段是text类型,采用了ik分词器,里面的值是奋斗的时代,通过网上在线ik分词器,我们知道会分解成奋斗,奋,斗,时代,如图4,但是如果你用该字段的term或者terms查询,输入的关键字是奋斗的时代,因为输入的关键字不会分词,反而查不到该记录,如果你输入的关键字是奋斗就是可以的。
在这里插入图片描述

图4 奋斗的时代在线IK分词结果

  实现要求,依据province字段查询所有北京,上海,杭州公司的短信内容

  RESTFUL代码如下;

# from size类似于musql的limit
POST /sms-logs-index/_search
{
  "from": 0
  ,"size": 20
  , "query": 
  {
    "terms": {
      "province": [
        "北京1",
        "上海",
        "杭州"
      ]
    }
    
  }
}

  Java代码如下;

    static RestHighLevelClient myClient= EsClient.getClient();  //获取操作ES的
    String index="sms-logs-index";

    @Test
    public void termsQuery() throws IOException {
        //1。创建request对象,查询用的对象一般都是SearchRequest对象
        SearchRequest mySearchRequest = new SearchRequest(index);

        //2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.from(0).size(10).query(QueryBuilders.termsQuery("province", "北京", "上海", "杭州")); //指定term查新条件

        mySearchRequest.source(builder);
        //3. 执行查询
        SearchResponse search = myClient.search(mySearchRequest, RequestOptions.DEFAULT);

        //4. 获取到_source中的数据,并展示
        for (SearchHit hit : search.getHits().getHits()) {
            Map<String, Object> result = hit.getSourceAsMap();
            System.out.println(result);
        }
    }

match_all查询

查询全部内容,不指定任何查询条件。
  实现要求,查询返回所有的记录。

  RESTFUL代码如下;

#match_all查询
POST /sms-logs-index/_search
{
"query": {
  "match_all": {}
}
}

  注意:如图5实际有12条数据,只返回了10条,是因为默认查询数据返回的结果比较大时,ES只返回前10条数据,即默认的size=10.如果需要返回更多的结果,可以改写size的大小
在这里插入图片描述

图5 默认的查询结果和实际结果少
   增大size的大小的RESTFUL代码如下,结果如图6;
#match_all查询
POST /sms-logs-index/_search
{
  "from": 0, 
  "size": 20, 
  
"query": {
  "match_all": {}
}
}

在这里插入图片描述

图6 增大size大小返回更多的结果

  Java代码如下;

    static RestHighLevelClient myClient= EsClient.getClient();  //获取操作ES的
    String index="sms-logs-index";

    @Test
    public void matchAllQuery() throws IOException {
        //1。创建request对象,查询用的对象一般都是SearchRequest对象
        SearchRequest request = new SearchRequest(index);

        //2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
        //虽然matchall没有条件,但是还是要指定查询类型为matchall
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchAllQuery());
        builder.size(20);   //ES默认只查询10条记录,即默认size=10,如果需要查询更多,则需要加到size的值
        request.source(builder);

        //3. 执行查询
        SearchResponse response = myClient.search(request, RequestOptions.DEFAULT);


        //4. 获取到_source中的数据,并展示
        //遍历输出每个文档
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
        //输出总文档数
        System.out.println(response.getHits().getHits().length);
        
    }

match查询

match查询属于高层查询,会根据你查询的字段的类型不一致,采用不同的查询方式。

  • 如果查询的是日期或者数值的字段,他会自动将你的字符串查询内容转换成日期或者数值对待;
  • 如果查询的内容是一个不能被分词的字段(keyword).match查询不会对你的指定查询关键字进行分词;
  • 如果查询的内容是一个可以分词的字段(text),match会将你指定的查询内容根据一定的方式去分词,然后去分词库中匹配指定的内容。
    总而言之:match查询,实际底层就是多个term查询,将多个term查询的结果汇集到一起返回给你。

  实现要求,依据smsContent字段查询所有包含魅力宣传的公司的短信内容

  RESTFUL代码如下;

# from size类似于musql的limit
#match查询
POST /sms-logs-index/_search
{
  "from": 0
  , "size": 20
  , "query": {
    "match": {
      "smsContent": "魅力宣传"
    }
  }
}


  Java代码如下;

    static RestHighLevelClient myClient= EsClient.getClient();  //获取操作ES的
    String index="sms-logs-index";

    @Test
    public void matchQuery() throws IOException {
        //1。创建request对象,查询用的对象一般都是SearchRequest对象
        SearchRequest request = new SearchRequest(index);

        //2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchQuery("smsContent","魅力宣传"));
        builder.size(20);   //ES默认只查询10条记录,即默认size=10,如果需要查询更多,则需要加到size的值
        request.source(builder);

        //3. 执行查询
        SearchResponse response = myClient.search(request, RequestOptions.DEFAULT);


        //4. 获取到_source中的数据,并展示
        //遍历输出每个文档
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
        //输出总文档数
        System.out.println(response.getHits().getHits().length);

    }

布尔match查询

拥有match查询的特性,同时可以基于一个field匹配内容,采用and或者or的方式

  实现要求,依据smsContent字段查询所有即包含魅力宣传的公司的短信内容

  RESTFUL代码如下;

# from size类似于musql的limit
#布尔match查询,内容即包含魅力,也包含宣传,是个and的关系
POST /sms-logs-index/_search
{
  "from": 0,
  "size": 20, 
  "query": {
    "match": {
      "smsContent": 
      {
        "query": "魅力 宣传"
        , "operator": "and"
      }
    }
  }
}

#布尔match查询,内容包含魅力,或者宣传,是个or的关系
POST /sms-logs-index/_search
{
  "from": 0,
  "size": 20, 
  "query": {
    "match": {
      "smsContent": 
      {
        "query": "魅力 宣传"
        , "operator": "or"
      }
    }
  }
}

  Java代码如下;

    static RestHighLevelClient myClient= EsClient.getClient();  //获取操作ES的
    String index="sms-logs-index";

    @Test
    public void booleanMatchQuery() throws IOException {
        //1。创建request对象,查询用的对象一般都是SearchRequest对象
        SearchRequest request = new SearchRequest(index);

        //2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.matchQuery("smsContent","魅力 宣传").operator(Operator.AND)); //根据业务选择AND 或者OR
        builder.size(20);   //ES默认只查询10条记录,即默认size=10,如果需要查询更多,则需要加到size的值
        request.source(builder);

        //3. 执行查询
        SearchResponse response = myClient.search(request, RequestOptions.DEFAULT);


        //4. 获取到_source中的数据,并展示
        //遍历输出每个文档
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
        //输出总文档数
        System.out.println(response.getHits().getHits().length);

    }

multi_match查询

拥有match的特性,multi_match针对多个field进行检索,多个field对应一个查询的关键字;

  实现要求,查询包含北京的字段province或者字段smsContent

  RESTFUL代码如下;

# multi_match查询
POST /sms-logs-index/_search
{
  "query": {
    "multi_match": {
      "query": "北京",
      "fields": ["province","smsContent"]
    }
  }
}


  Java代码如下;

    static RestHighLevelClient myClient= EsClient.getClient();  //获取操作ES的
    String index="sms-logs-index";

    @Test
    public void multiMatchQuery() throws IOException {
        //1。创建request对象,查询用的对象一般都是SearchRequest对象
        SearchRequest request = new SearchRequest(index);

        //2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.multiMatchQuery("北京","province","smsContent")); //根据业务选择AND 或者OR
        builder.size(20);   //ES默认只查询10条记录,即默认size=10,如果需要查询更多,则需要加到size的值
        request.source(builder);

        //3. 执行查询
        SearchResponse response = myClient.search(request, RequestOptions.DEFAULT);


        //4. 获取到_source中的数据,并展示
        //遍历输出每个文档
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
        //输出总文档数
        System.out.println(response.getHits().getHits().length);

    }

  以上两种最重要的查询term查询和match查询就讲到这里,接下来再看看一些其他的常用查询。

根据文档id查询(单个id)

ES每一行数据,即文档都会有一个id,如果指定某一列field值作为id,则该列field必须为唯一键,类似于MySQL的UK;不过不指定,ES会自动生成,常常为了更好的定位数据,会指定一列满足UK的field作为文档的id,接下来我们说一下根据id查询。
类似MySQL的 where id=?

  实现要求,查询索引sms-logs-index 文档id等于1的文档。

  RESTFUL代码如下;

#根据文档的id查询
GET /sms-logs-index/_doc/1

  Java代码如下;


    static RestHighLevelClient myClient= EsClient.getClient();  //获取操作ES的
    String index="sms-logs-index";

    @Test
    public void findById() throws IOException {
        //1.创建GetRequest
        GetRequest getRequest = new GetRequest(index,"1");

        //2.执行查询
        GetResponse response = myClient.get(getRequest, RequestOptions.DEFAULT);


        //3.输出结果
        System.out.println(response.getSourceAsMap());
        
    }

s

根据文档ids查询(多个id)

根据多个id查询,类似MySQL中的where id in(id1,id2,id3)

  实现要求,查询索引sms-logs-index 文档id为1,2,3的文档。

  RESTFUL代码如下;

#ids查询
POST /sms-logs-index/_search
{
  "query": {
    "ids": {
      "values": [1,2,3]
    }
  }
}



  Java代码如下;

    static RestHighLevelClient myClient= EsClient.getClient();  //获取操作ES的
    String index="sms-logs-index";

    @Test
    public void findByIds() throws IOException {
        //1。创建request对象,查询用的对象一般都是SearchRequest对象
        SearchRequest request = new SearchRequest(index);

        //2,指定查询条件,依赖查询条件的对象SearchSourceBuilder的对象
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.query(QueryBuilders.idsQuery().addIds("1","2","3"));
        builder.size(20);   //ES默认只查询10条记录,即默认size=10,如果需要查询更多,则需要加到size的值
        request.source(builder);

        //3. 执行查询
        SearchResponse response = myClient.search(request, RequestOptions.DEFAULT);
        
        //4. 获取到_source中的数据,并展示
        //遍历输出每个文档
        for (SearchHit hit : response.getHits().getHits()) {
            System.out.println(hit.getSourceAsMap());
        }
        //输出总文档数
        System.out.println(response.getHits().getHits().length);
    }

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐