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); 
    } 
 

本文参考链接:https://blog.csdn.net/LXWalaz1s1s/article/details/108704773
评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!