1 安装

见我另外一篇文章:

Elasticsearch安装指南 


2.原生操作

2.1 kibana操作

##################################################################################################################
#分词
POST _analyze
{
  "analyzer": "standard",
  "text": "中华人民共和国"
}

# 分词
POST _analyze
{
  "analyzer": "ik_smart",
  "text": "中华人民共和国"
}

# 分词
POST _analyze
{
  "analyzer": "ik_max_word",
  "text": "中华人民共和国"
}

##################################################################################################################

# 创建索引库
PUT /wenchen
{
  "mappings": {
    "properties": {
      "info": {
        "type": "text",
        "analyzer": "ik_smart"
      },
      "age": {
        "type": "byte"
      },
      "email": {
        "type": "keyword",
        "index": false
      },
      "name": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "keyword"
          },
          "lastName": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

# 查询索引库
GET /wenchen

# 删除索引库
DELETE /wenchen

#索引库和mapping一旦创建就不能修改,但是可以添加新字段,语法如下
PUT /wenchen/_mapping
{
  "properties":{
    "id":{
      "type":"byte"
    }
  }
}

##################################################################################################################

# 添加一条数据
POST /wenchen/_doc/1
{
  "info":"后端开发码农",
  "email":"2074536824@qq.com",
  "name":{
    "firstName":"尘",
    "lastName":"问"
  }
}

# 查询数据
GET /wenchen/_doc/1

# 删除数据
DELETE /wenchen/_doc/1

# 全量修改数据
PUT /wenchen/_doc/1
{
  "info": "后端开发码农1",
  "email": "2074536824@qq.com",
  "name": {
    "firstName": "尘1",
    "lastName": "问1"
  }
}

# 局部修改(增量修改)
POST /wenchen/_update/1
{
  "doc": {
    "email":"2656356121@qq.com"
  }
}

##################################################################################################################

# 批量处理
# 批量新增
POST /_bulk
{"index":{"_index":"wenchen","_id":3}}
{"info":"前端开发码农","email":"2074536824@qq.com","age":26,"name":{"firstName":"尘1","lastName":"问1"}}
{"index":{"_index":"wenchen","_id":4}}
{"info":"前端开发码农1","email":"2074536824@qq.com","age":28,"name":{"firstName":"尘2","lastName":"问2"}}

# 批量删除
POST /_bulk
{"delete":{"_index":"wenchen","_id":3}}
{"delete":{"_index":"wenchen","_id":4}}

# 批量更新等同理

##################################################################################################################
# 商品索引库
PUT /wenchenmall
{
  "mappings": {
    "properties": {
      "id":{
        "type": "keyword"
      },
      "neme": {
        "type": "text",
        "analyzer": "ik_smart"
      },
      "price":{
        "type": "integer"
      },
      "image":{
        "type": "keyword",
        "index": false
      },
      "category":{
        "type": "keyword",
        "index": false
      },
      "brand":{
        "type": "keyword"
      },
      "sold":{
        "type": "integer"
      },
      "commentCount":{
        "type": "integer",
        "index": false
      },
      "isAD":{
        "type": "boolean"
      },
      "updateTime":{
        "type": "date"
      }
    }
  }
}

##################################################################################################################

# 叶子查询
# 查询所有
GET /wenchenmall/_search
{
  "query": {
    "match_all": {}
  }
}

#全文检索查询
# match所有
GET /wenchenmall/_search
{
  "query": {
    "match": {
      "name": "葡萄"
    }
  }
}
# Multi_match所有,可以多个字段查询
GET /wenchenmall/_search
{
  "query": {
    "multi_match": {
      "query": "葡",
      "fields": ["name"]
    }
  }
}

# 精确查询(推荐查找keyword)
# term
GET /wenchenmall/_search
{
  "query": {
    "term": {
      "brand": {
        "value": "brand"
      }
    }
  }
}

# range 所有
# price大于等于50小于500
GET /wenchenmall/_search
{
  "query": {
    "range": {
      "price": {
        "gte": 50,
        "lt": 500
      }
    }
  }
}


# ids所有
# 没有得分
GET /wenchenmall/_search
{
  "query": {
    "ids": {
      "values": ["1","2"]
    }
  }
}

##################################################################################################################

# 复合查询
# must相当于and参与算分
# should相当于or参与算分
# must_not相当于note,即:非,参与算分
# filter相当于and不参与算分
GET /wenchenmall/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "name": "葡"
          }
        }
      ],
      "filter": [
        {
          "term": {
            "brand": "brand"
          }
        },
        {
          "range": {
            "price": {
              "gte": 50,
              "lte": 50000
            }
          }
        }
      ]
    }
  }
}

# 排序和分页
# 排序查询
# 按销量降序,当销量一样是安价格升序
GET /wenchenmall/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "sold": {
        "order": "desc"
      },
      "price": {
        "order": "asc"
      }
    }
  ]
}

##################################################################################################################

# 排序及分页查询
# 按销量降序,当销量一样是安价格升序,查寻第二页,每页三条数据3条
GET /wenchenmall/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "sold": {
        "order": "desc"
      },
      "price": {
        "order": "asc"
      }
    }
  ],
  "from": 3,
  "size": 3
}

# 深度分页
# 深度越深需要的性能越高
# 用search after解决
# 缺点只能i页到i+1页,不能跳这查


##################################################################################################################
# 高亮显示,"pre_tags": "<em>","post_tags": "</em>",可以不要,默认是<em>
GET /wenchenmall/_search
{
  "query": {
    "match": {
      "name": "葡"
    }
  },
  "highlight": {
    "fields": {
      "name": {
        "pre_tags": "<em>",
        "post_tags": "</em>"
      }
    }
  }
}

GET /wenchenmall/_search
{
  "query": {
    "match": {
      "name": "葡"
    }
  },
  "highlight": {
    "fields": {
      "name": {}
    }
  }
}

##################################################################################################################


#聚合
/**
 * 数据聚合
 * 桶聚合
 *  termAggregation: 按照文档字段值分组
 *  date histogram: 按照日期阶梯分组,例如一个周为一组,一个月为一组
 *
 * 度量聚合
 *  avg:求平均值
 *  max:求最大值
 *  min:求最小值
 *  stats:同时求max,min,avg,sum
 *
 *  管道聚合: 其他聚合的结果为基础做聚合
 */
 
 # 分组
GET /wenchenmall/_search
{
  "size": 0,
  "aggs": {
    "category_agg": {
      "terms": {
        "field": "category",
        "size": 10
      }
    },
    "brand_agg":{
      "terms": {
        "field": "brand",
        "size": 10
      }
    }
  }
}

# 限定分组(带条件的)
GET /wenchenmall/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "brand": "苦瓜"
          },
          "range": {
            "price": {
              "gt": 0
            }
          }
        }
      ]
    }
  },
  "size": 0,
  "aggs": {
    "category_agg": {
      "terms": {
        "field": "category",
        "size": 10
      }
    },
    "brand_agg": {
      "terms": {
        "field": "brand",
        "size": 10
      }
    }
  }
}

# 满足query条件的数据聚合
GET /wenchenmall/_search
{
    "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "brand": "苦瓜"
          }
        }
      ]
    }
  },
  "size": 0,
  "aggs": {
    "category_agg": {
      "terms": {
        "field": "category",
        "size": 10
      }
    },
    "brand_agg": {
      "terms": {
        "field": "brand",
        "size": 10
      },
      "aggs": {
        "price_stats": {
          "stats": {
            "field": "price"
          }
        }
      }
    }
  }
}

2.2 java客户端操作

添加maven坐标,版本对应es版本

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>${elasticsearch.version}</version>
</dependency>
2.2.1 索引库操作
package com.wenchen.es;

import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;

/**
 * 索引库操作
 */
@SpringBootTest
class ElasticIndexTest {

    /**
     * 操作es需要的客户端
     */
    private RestHighLevelClient restHighLevelClient;

    /**
     * 创建索引库需要的数据
     */
    private static final String MAPPING_TEMPLATE = "{\n" +
            "  \"mappings\": {\n" +
            "    \"properties\": {\n" +
            "      \"id\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"neme\": {\n" +
            "        \"type\": \"text\",\n" +
            "        \"analyzer\": \"ik_smart\"\n" +
            "      },\n" +
            "      \"price\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"image\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "      \"category\":{\n" +
            "        \"type\": \"keyword\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "      \"brand\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"sold\":{\n" +
            "        \"type\": \"integer\"\n" +
            "      },\n" +
            "      \"commentCount\":{\n" +
            "        \"type\": \"integer\",\n" +
            "        \"index\": false\n" +
            "      },\n" +
            "      \"isAD\":{\n" +
            "        \"type\": \"boolean\"\n" +
            "      },\n" +
            "      \"updateTime\":{\n" +
            "        \"type\": \"date\"\n" +
            "      }\n" +
            "    }\n" +
            "  }\n" +
            "}";

    /**
     * 初始化连接
     */
    @BeforeEach
    void setup(){
        restHighLevelClient = new RestHighLevelClient(
                RestClient.builder(HttpHost.create("http://192.168.117.137:9200"))
        );
    }

    /**
     * 关闭连接
     */
    @AfterEach
    void teardown(){
        try {
            restHighLevelClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 创建wenchenmall索引库
     * @throws IOException
     */
    @Test
    void testCreateIndex() throws IOException {
        CreateIndexRequest indexRequest = new CreateIndexRequest("wenchenmall");
        indexRequest.source(MAPPING_TEMPLATE, XContentType.JSON);
        restHighLevelClient.indices().create(indexRequest, RequestOptions.DEFAULT);
    }

    /**
     * 获取索引库为wenchenmall的数据
     * @throws IOException
     */
    @Test
    void testGetIndex() throws IOException {
        GetIndexRequest indexRequest = new GetIndexRequest("wenchenmall");
        GetIndexResponse getIndexResponse = restHighLevelClient.indices().get(indexRequest, RequestOptions.DEFAULT);
        System.out.println("Indices = " + getIndexResponse.getIndices());

    }

    /**
     * 删除索引库
     * @throws IOException
     */
    @Test
    void testDeleteIndex() throws IOException {
        DeleteIndexRequest indexRequest = new DeleteIndexRequest("wenchenmall");
        restHighLevelClient.indices().delete(indexRequest, RequestOptions.DEFAULT);
    }

}
2.2.2 对文档操作
package com.wenchen.es;

import cn.hutool.json.JSONUtil;
import com.wenchen.es.doman.Demo;
import org.apache.http.HttpHost;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Random;

//文档操作
@SpringBootTest
class ElasticDocumentTest {

    private RestHighLevelClient restHighLevelClient;


    @BeforeEach
    void setup() {
        restHighLevelClient = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.117.137:9200")));
    }

    @AfterEach
    void teardown() {
        try {
            restHighLevelClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 添加修改索引库为wenchenmall的id为1的数据
     *
     * @throws IOException
     */
    @Test
    void testIndexDocument() throws IOException {//全量修改和新增同接口
        IndexRequest request = new IndexRequest("wenchenmall").id("1");
        Demo demo = Demo.builder().id("1").name("葡萄").price(128).image("http://127.0.0.1/a.jpg").category("分类").brand("brand").sold(25).commentCount(35).isAD(true).update(LocalDateTime.of(2024, 5, 19, 12, 12, 12)).build();
        request.source(JSONUtil.toJsonStr(demo), XContentType.JSON);
        restHighLevelClient.index(request, RequestOptions.DEFAULT);

        //        for (int j = 1001; j < 3000; j++) {
        //            Random random = new Random();
        //            int i = random.nextInt(100000000);
        //            IndexRequest request = new IndexRequest("wenchenmall").id(j+"");
                Demo demo = new Demo("1","葡萄",128,"http://127.0.0.1/a.jpg","分类","brand",25,35,true,"2022-01-01 00:00:00");
        //            Demo demo = Demo.builder().id(j+"").name((i%5==1?"葡萄":"")+(i%5==0?"苹果":"")+(i%5==2?"杨梅":"")+(i%5==3?"土豆":"")+(i%5==4?"青菜":"")+(i%5==0?"黄瓜":"")+(i%5==1?"苦瓜":"")+(i%5==2?"波罗":"")+(i%5==3?"辣椒":"")+(i%5==4?"樱桃":"")).price(128).image("http://127.0.0.1/a.jpg").category("分类").brand((i%10==1?"葡萄":"")+(i%10==0?"苹果":"")+(i%10==2?"杨梅":"")+(i%10==3?"土豆":"")+(i%10==4?"青菜":"")+(i%10==5?"黄瓜":"")+(i%10==6?"苦瓜":"")+(i%10==7?"波罗":"")+(i%10==8?"辣椒":"")+(i%10==9?"樱桃":"")).sold(25).commentCount(35).isAD(true).update(LocalDateTime.of(2024, 5, 19, 12, 12, 12)).build();
        //            request.source(JSONUtil.toJsonStr(demo), XContentType.JSON);
        //            restHighLevelClient.index(request, RequestOptions.DEFAULT);
        //        }
    }

    /**
     * 获取es中wenchenmall索引库的id为1的数据
     *
     * @throws IOException
     */
    @Test
    void testGetDocument() throws IOException {//获取es中wenchenmall索引库的id为1的数据
        GetRequest request = new GetRequest("wenchenmall", "1");
        GetResponse documentFields = restHighLevelClient.get(request, RequestOptions.DEFAULT);
        String json = documentFields.getSourceAsString();
        System.out.println("json = " + json);
        Demo bean = JSONUtil.toBean(json, Demo.class);
        System.out.println("bean = " + bean);
    }

    /**
     * 局部修改
     * 局部更新索引库为wenchenmall的id为1的数据
     *
     * @throws IOException
     */
    @Test
    void testUpdateDocument() throws IOException {//局部修改
        UpdateRequest updateRequest = new UpdateRequest("wenchenmall", "1");
        updateRequest.doc("price", 4567);
        restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
    }

    /**
     * 删除索引库为wenchenmall的id为1的数据
     *
     * @throws IOException
     */
    @Test
    void testDeleteDocument() throws IOException {
        DeleteRequest indexRequest = new DeleteRequest("wenchenmall");
        restHighLevelClient.delete(indexRequest, RequestOptions.DEFAULT);
    }

}
2.2.3 批量操作
package com.wenchen.es;

import cn.hutool.json.JSONUtil;
import com.wenchen.es.doman.Demo;
import org.apache.http.HttpHost;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.time.LocalDateTime;

//文档操作
@SpringBootTest
class ElasticBulkDocumentTest {

    private RestHighLevelClient restHighLevelClient;


    @BeforeEach
    void setup() {
        restHighLevelClient = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.117.137:9200")));
    }

    @AfterEach
    void teardown() {
        try {
            restHighLevelClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 批量操作
     */
    @Test
    void testBulkDoc() throws IOException {
        //创建批量请求
        BulkRequest bulkRequest = new BulkRequest();
        //准备请求参数
        //新增
        bulkRequest.add(new IndexRequest("wenchenmall").id("2").source(JSONUtil.toJsonStr(Demo.builder().id("2").name("诗画").price(128).image("http://127.0.0.1/a.jpg").category("分类").brand("brand").sold(25).commentCount(35).isAD(true).update(LocalDateTime.of(2024, 5, 19, 12, 12, 12)).build()), XContentType.JSON));
        bulkRequest.add(new IndexRequest("wenchenmall").id("3").source(JSONUtil.toJsonStr(Demo.builder().id("3").name("胖狗").price(128).image("http://127.0.0.1/a.jpg").category("分类").brand("brand").sold(25).commentCount(35).isAD(true).update(LocalDateTime.of(2024, 5, 19, 12, 12, 12)).build()), XContentType.JSON));
        bulkRequest.add(new IndexRequest("wenchenmall").id("4").source(JSONUtil.toJsonStr(Demo.builder().id("4").name("恶劣").price(128).image("http://127.0.0.1/a.jpg").category("分类").brand("brand").sold(25).commentCount(35).isAD(true).update(LocalDateTime.of(2024, 5, 19, 12, 12, 12)).build()), XContentType.JSON));
        //删除
        bulkRequest.add(new DeleteRequest("wenchenmall", "3"));
        bulkRequest.add(new DeleteRequest("wenchenmall", "4"));
        //修改
        bulkRequest.add(new UpdateRequest("wenchenmall", "2").doc("price", 4567));
        bulkRequest.add(new UpdateRequest("wenchenmall", "1").doc("price", 1234));
        //发送请求
        restHighLevelClient.bulk(bulkRequest, RequestOptions.DEFAULT);
    }



    /**
     * 获取es中wenchenmall索引库的id为1的数据
     * @throws IOException
     */
    @Test
    void testGetDocument() throws IOException {//获取es中wenchenmall索引库的id为1的数据
        GetRequest request = new GetRequest("wenchenmall", "2");
        GetResponse documentFields = restHighLevelClient.get(request, RequestOptions.DEFAULT);
        String json = documentFields.getSourceAsString();
        System.out.println("json = " + json);
        Demo bean = JSONUtil.toBean(json, Demo.class);
        System.out.println("bean = " + bean);
    }


}
2.2.4 文档搜索
2.2.4.1 必要的实体类
package com.wenchen.es.doman;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

/**
 * Author: wen-chen
 * Date: 2024/5/18
 */
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Demo {
    private String id;

    private String name;

    private Integer price;

    private String image;

    private String category;

    private String brand;

    private Integer sold;

    private Integer commentCount;

    private boolean isAD;

    private LocalDateTime update;
}
2.2.4.1 代码
package com.wenchen.es;


import cn.hutool.json.JSONUtil;
import com.wenchen.es.doman.Demo;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.naming.directory.SearchResult;
import java.io.IOException;

//搜索排序等操作
@SpringBootTest
class ElasticSearchTest {

    private RestHighLevelClient restHighLevelClient;


    @BeforeEach
    void setup() {
        restHighLevelClient = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.117.137:9200")));
    }

    @AfterEach
    void teardown() {
        try {
            restHighLevelClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * matchAllQuery查询wenchenmall的文档数据
     *
     * @throws IOException
     */
    @Test
    void testMatchAll() throws IOException {
        //创建request
        SearchRequest searchRequest = new SearchRequest("wenchenmall");
        //配置request参数
        searchRequest.source().query(QueryBuilders.matchAllQuery()).size(3).from(2);
        //执行request
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        //处理response
        //打印response
        System.out.println("response = " + response);
        //获取hits
        SearchHits hits = response.getHits();
        //获取总记录数
        System.out.println("TotalHits:" + hits.getTotalHits().value);
        //获取hits中的每条记录
        for (SearchHit hit : hits.getHits()) {
            //获取json字符串
            String json = hit.getSourceAsString();
            //转换为bean
            Demo bean = JSONUtil.toBean(json, Demo.class);
            //打印bean
            System.out.println("bean = " + bean);
        }
    }


    /**
     * matchQuery查询wenchenmall的文档数据
     */
    @Test
    void testMatch() throws IOException {
        //创建request
        SearchRequest searchRequest = new SearchRequest("wenchenmall");
        //配置request参数
        searchRequest.source().query(QueryBuilders.matchQuery("name", "葡"));
        //执行request
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        //处理response
        //打印response
        System.out.println("response = " + response);
        //获取hits
        SearchHits hits = response.getHits();
        //获取总记录数
        System.out.println("TotalHits:" + hits.getTotalHits().value);
        //获取hits中的每条记录
        for (SearchHit hit : hits.getHits()) {
            //获取json字符串
            String json = hit.getSourceAsString();
            //转换为bean
            Demo bean = JSONUtil.toBean(json, Demo.class);
            //打印bean
            System.out.println("bean = " + bean);
        }
    }

    /**
     * multiMatchQuery查询wenchenmall的文档数据
     */
    @Test
    void testMultiMatch() throws IOException {
        //创建request
        SearchRequest searchRequest = new SearchRequest("wenchenmall");
        //配置request参数
        searchRequest.source().query(QueryBuilders.multiMatchQuery("葡", "name"));
        //执行request
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        //处理response
        //打印response
        System.out.println("response = " + response);
        //获取hits
        SearchHits hits = response.getHits();
        //获取总记录
        System.out.println("TotalHits:" + hits.getTotalHits().value);

        //获取hits中的每条记录
        for (SearchHit hit : hits.getHits()) {
            //获取json字符串
            String json = hit.getSourceAsString();

            //转换为bean
            Demo bean = JSONUtil.toBean(json, Demo.class);

            //打印bean
            System.out.println("bean = " + bean);
        }
    }

    /**
     * rangeQuery查询wenchenmall的文档数据
     */
    @Test
    void testRangeQuery() throws IOException {

        //创建request
        SearchRequest searchRequest = new SearchRequest("wenchenmall");
        //配置request参数
        searchRequest.source().query(QueryBuilders.rangeQuery("price").gte(100).lte(200)).size(1).from(0);
        //执行request
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        //处理response
        //打印response
        System.out.println("response = " + response);
        //获取hits
        SearchHits hits = response.getHits();
        //获取总记录
        System.out.println("TotalHits:" + hits.getTotalHits().value);
        //获取hits中的每条记录
        for (SearchHit hit : hits.getHits()) {
            //获取json字符串
            String json = hit.getSourceAsString();

            //转换为bean
            Demo bean = JSONUtil.toBean(json, Demo.class);

            //打印bean
            System.out.println("bean = " + bean);
        }
    }


    /**
     * 复合查询
     * price在0到2000000之间,并且brand是苹果,并且name包含瓜,或者不包含葡萄
     * 查出的数据price从高到低排序,price相同id从低到高排序
     * boolQuery查询wenchenmall的文档数据
     */
    @Test
    void testBoolQuery() throws IOException {

        //创建request
        SearchRequest searchRequest = new SearchRequest("wenchenmall");
        //配置request参数
        searchRequest.source().query(QueryBuilders.boolQuery()
                .must(QueryBuilders.matchQuery("name", "瓜"))
                .must(QueryBuilders.rangeQuery("price").gte(0).lte(2000000))
                .filter(QueryBuilders.termQuery("brand", "苹果"))
                .mustNot(QueryBuilders.matchQuery("name", "番茄"))
                .should(QueryBuilders.matchQuery("name", "葡萄"))
        ).from(0).size(1000)
                .sort(SortBuilders.fieldSort("price").order(SortOrder.DESC))
                .sort(SortBuilders.fieldSort("id").order(SortOrder.ASC));

        //执行request
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        //处理response
        //打印response
//        System.out.println("response = " + response);

        //获取hits
        SearchHits hits = response.getHits();

        //获取总记录
        System.out.println("TotalHits:" + hits.getTotalHits().value);

        //获取hits中的每条记录
        for (SearchHit hit : hits.getHits()) {
            //获取json字符串
            String json = hit.getSourceAsString();
            //转换为bean
            Demo bean = JSONUtil.toBean(json, Demo.class);
            //打印bean
            System.out.println("bean = " + bean);
        }
    }

}
2.2.5 文档高亮
package com.wenchen.es;


import cn.hutool.json.JSONUtil;
import com.wenchen.es.doman.Demo;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchScrollRequestBuilder;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;

//搜索排序等操作
@SpringBootTest
class ElasticHighlightTest {

    private RestHighLevelClient restHighLevelClient;


    @BeforeEach
    void setup() {
        restHighLevelClient = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.117.137:9200")));
    }

    @AfterEach
    void teardown() {
        try {
            restHighLevelClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * multiMatchQuery查询wenchenmall的文档数据
     * highlighter和query平级
     */
    @Test
    void testMultiMatch() throws IOException {
        //创建request
        SearchRequest searchRequest = new SearchRequest("wenchenmall");
        //配置request参数
        searchRequest.source()
                .query(QueryBuilders.multiMatchQuery("葡萄", "name"))
                .highlighter(SearchSourceBuilder.highlight().field("name").preTags("<em>").postTags("</em>"));
        //执行request
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        //处理response
        //打印response
        System.out.println("response = " + response);
        //获取hits
        SearchHits hits = response.getHits();
        //获取总记录
        System.out.println("TotalHits:" + hits.getTotalHits().value);

        //获取hits中的每条记录
        for (SearchHit hit : hits.getHits()) {
            //获取json字符串
            String json = hit.getSourceAsString();
            String name = new String();
            //转换为bean
            Demo bean = JSONUtil.toBean(json, Demo.class);
            if (hit.getHighlightFields() != null && !hit.getHighlightFields().isEmpty()) {
                for (Text str : hit.getHighlightFields().get("name").getFragments()) {
                    name += str.toString();
                }
                bean.setName(name);
            }

            //打印bean
            System.out.println("bean = " + bean);
        }
    }

    /**
     * 复合查询
     * price在0到2000000之间,并且brand是苹果,并且name包含瓜,或者不包含葡萄
     * 查出的数据price从高到低排序,price相同id从低到高排序
     * boolQuery查询wenchenmall的文档数据
     */
    @Test
    void testBoolQuery() throws IOException {

        //创建request
        SearchRequest searchRequest = new SearchRequest("wenchenmall");
        //配置request参数
        searchRequest.source().query(QueryBuilders.boolQuery()
                        .must(QueryBuilders.matchQuery("name", "瓜"))
                        .must(QueryBuilders.rangeQuery("price").gte(0).lte(2000000))
                        .filter(QueryBuilders.termQuery("brand", "苹果"))
                        .mustNot(QueryBuilders.matchQuery("name", "番茄"))
                        .should(QueryBuilders.matchQuery("name", "葡萄"))
                ).from(0).size(1000)
                .sort(SortBuilders.fieldSort("price").order(SortOrder.DESC))
                .sort(SortBuilders.fieldSort("id").order(SortOrder.ASC))
                .highlighter(SearchSourceBuilder.highlight().field("name"));


        //执行request
        SearchResponse response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        //处理response
        //打印response
//        System.out.println("response = " + response);

        //获取hits
        SearchHits hits = response.getHits();

        //获取总记录
        System.out.println("TotalHits:" + hits.getTotalHits().value);

        //获取hits中的每条记录
        for (SearchHit hit : hits.getHits()) {
            //获取json字符串
            String json = hit.getSourceAsString();
            String name = new String();

            //转换为bean
            Demo bean = JSONUtil.toBean(json, Demo.class);
            if (hit.getHighlightFields() != null && !hit.getHighlightFields().isEmpty()) {
                for (Text str : hit.getHighlightFields().get("name").getFragments()) {
                    name += str.toString();
                }
                bean.setName(name);
            }
            //打印bean
            System.out.println("bean = " + bean);
        }
    }

}
2.2.6 聚合操作
package com.wenchen.es;


import cn.hutool.json.JSONUtil;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.Stats;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;

//聚合操作
@SpringBootTest
class ElasticAggregationsTest {

    private RestHighLevelClient restHighLevelClient;


    @BeforeEach
    void setup() {
        restHighLevelClient = new RestHighLevelClient(RestClient.builder(HttpHost.create("http://192.168.117.137:9200")));
    }

    @AfterEach
    void teardown() {
        try {
            restHighLevelClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 数据聚合
     * 桶聚合
     * termAggregation: 按照文档字段值分组
     * date histogram: 按照日期阶梯分组,例如一个周为一组,一个月为一组
     * <p>
     * 度量聚合
     * avg:求平均值
     * max:求最大值
     * min:求最小值
     * stats:同时求max,min,avg,sum
     * <p>
     * 管道聚合: 其他聚合的结果为基础做聚合
     */

    @Test
    void testAggregations() throws IOException {
        //创建request对象
        SearchRequest searchRequest = new SearchRequest("wenchenmall");
        //定义聚合的名称
        String brandAggName = "brand_agg";
        //创建聚合对象
        //设置聚合的名称
        //设置聚合的类型
        //设置size返回的为0
        searchRequest.source().aggregation(
                AggregationBuilders.terms(brandAggName)
                        .field("brand").size(10)
        ).size(0);
        //执行请求
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        //输出结果
        System.out.println("search = " + search);

        //获取聚合结果
        Aggregations aggregations = search.getAggregations();
        //获取桶聚合结果
        Terms terms = aggregations.get(brandAggName);

        //输出结果
        for (Terms.Bucket bucket : terms.getBuckets()) {
            //获取
            String string = bucket.getKeyAsString();
            Number keyAsNumber = bucket.getDocCount();
            System.out.println("brand:" + string);
            System.out.println("count:" + keyAsNumber);
        }

    }

    @Test
    void testStatsAggregations() throws IOException {
        //创建request对象
        SearchRequest searchRequest = new SearchRequest("wenchenmall");
        //定义聚合的名称
        String brandAggName = "brand_agg";
        //创建聚合对象
        //设置聚合的名称
        //设置聚合的类型
        //设置size返回的为0
        searchRequest.source().aggregation(
                AggregationBuilders.terms(brandAggName)
                        .field("brand")
                        .subAggregation(AggregationBuilders.stats("stats_agg").field("price"))
        ).size(0);
        //执行请求
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        //输出结果
        System.out.println("search = " + search);

        //获取聚合结果
        Aggregations aggregations = search.getAggregations();
        //获取桶聚合结果
         Terms terms = aggregations.get(brandAggName);

        //输出结果
        for (Terms.Bucket bucket : terms.getBuckets()) {
            //获取
            String string = bucket.getKeyAsString();
            Number keyAsNumber = bucket.getDocCount();
            System.out.println("brand:" + string);
            System.out.println(" count:" + keyAsNumber);

            Aggregations aggregations1 = bucket.getAggregations();
            Stats stats = aggregations1.get("stats_agg");
            System.out.println(" -平均值:"+stats.getAvg());
            System.out.println(" -最大值:"+stats.getMax());
            System.out.println(" -最小值:"+stats.getCount());
            System.out.println(" -求和:"+stats.getSum());

        }

    }
}