Elasticsearch (ES) (上万字)详细学习总结

一、认识ES

二、ES相关安装和部署(elasticsearch 、kbana、ik)

这部分的内容可以查看我之前写的Docker常用部署这篇文章

三、Mapping映射

3.1 Mapping映射属性

3.2 索引库操作

3.2.1 遵循Restful规范说明

3.2.2 具体使用方式说明

3.2.3增删改查示例

复制代码
#创建
PUT /heima
{
  "mappings":{
    "properties": {
      "info":{
        "type": "text",
        "analyzer": "ik_smart"
      },
      "email": {
        "type": "keyword",
        "index": false
      },
      "name": {
        "type": "object",
        "properties": {
          "firstName":{
            "type": "keyword"
          },
          "lastName": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

#查询
GET /heima

#删除
DELETE /heima

#添加
PUT /heima/_mapping
{
  "properties":{
    "age":{
      "type":"byte"
    }
  }
}

3.2.4 总结

3.3 文档的操作

3.3.1 文档的增删改查示例

复制代码
#新增文档(如果已经存在则进行修改)
POST /heima/_doc/1
{
  "info": "Java入门到精通",
  "email": "csh@qq.com",
  "name": {
    "firstName": "云",
    "lastName": "赵"
  }
}

#查询文档
GET /heima/_doc/1

#删除文档
DELETE /heima/_doc/1


#全量修改(直接覆盖之前的文档,如果不存在该文档则会创建新的文档)
PUT /heima/_doc/1
{
   "info": "Python入门到精通",
  "email": "csh@163.com",
  "name": {
    "firstName": "白",
    "lastName": "李"
  }
}

#增量修改(局部修改)
POST /heima/_update/1
{
  "doc":{
    "email":"333@163.com"
  }
}

3.3.2 文档批量处理

复制代码
#批量添加
POST /_bulk
{"index": {"_index" : "heima" , "_id":1}}
{"info":"Java入门到精通","email":"csh@qq.com","name":{"firstName": "云","lastName": "赵"}}
{"index": {"_index" : "heima" , "_id":2}}
{"info":"Python入门到精通","email":"csh@163.com","name":{"firstName": "白","lastName": "李"}}

#批量删除
POST /heima/_bulk
{"delete": {"_index" : "heima" , "_id":1}}
{"delete": {"_index" : "heima" , "_id":2}}

3.3.3 总结

四、JavaRestClient(索引库)

4.1 客户端初始化

第一步:

引入依赖:

复制代码
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
        </dependency>

第二步:

在Spring-boot-dependency中找出<elaticsearch.version>7.17.0</elaticsearch.version>,

将其复制在父工程的<properties></properties>中修改版本号好为7.12.1(可根据自己所需要的版本进行修改

第三步:通过RestHighLevelClient使用ES

建立ES连接示例:

复制代码
package com.etc.search;

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
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 TripSearchApplicationTests {

    private RestHighLevelClient client;

    @Test
    void testConnection() {
        System.out.println("client: "+client);
    }

    @BeforeEach
    void setUp(){
        client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.92.136:9200")
        ));
    }

    @AfterEach
    void tearDown() throws IOException{
        if(client != null){
            client.close();
        }
    }


}

4.2 商品映射Mapping

kibana创建示例:

复制代码
PUT /item
{
  "mappings": {
    "properties": {
      "id":{
        "type": "keyword"
      },
      "name":{
        "type": "text",
        "analyzer": "ik_smart"
      },
      "price":{
        "type": "integer"
      },
      "image":{
        "type": "keyword",
        "index": false
      },
      "category":{
        "type":"keyword"
      },
      "brand":{
        "type": "keyword"
      },
      "sold":{
        "type": "integer"
      },
      "commentCount":{
        "type": "integer",
        "index": false
      },
      "isAD":{
        "type": "boolean"
      },
      "updateTime":{
        "type": "date"
      }
    }
  }
}

4.3 使用Java客户端示例:

复制代码
package com.etc.search;

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.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 org.springframework.web.bind.annotation.DeleteMapping;

import java.io.IOException;

@SpringBootTest
class TripSearchApplicationTests {

    private RestHighLevelClient client;

    @Test
    void testConnection() {
        System.out.println("client: "+client);
    }

    @Test
    void testCreateIndex() throws IOException{
        CreateIndexRequest request = new CreateIndexRequest("items");
        request.source(MAPPING_TEMPLATE, XContentType.JSON);
        client.indices().create(request, RequestOptions.DEFAULT);
    }

    @Test
    void testGetIndex() throws IOException{
        GetIndexRequest request = new GetIndexRequest("items");
        boolean exists =  client.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println("exists:"+exists);
    }

    @Test
    void testDeleteIndex() throws IOException{
        DeleteIndexRequest request = new DeleteIndexRequest("items");

        client.indices().delete(request, RequestOptions.DEFAULT);
    }

    @BeforeEach
    void setUp(){
        client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.92.136:9200")
        ));
    }

    @AfterEach
    void tearDown() throws IOException{
        if(client != null){
            client.close();
        }
    }

    private static final String MAPPING_TEMPLATE = "{\n" +
            "  \"mappings\": {\n" +
            "    \"properties\": {\n" +
            "      \"id\":{\n" +
            "        \"type\": \"keyword\"\n" +
            "      },\n" +
            "      \"name\":{\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" +
            "      },\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" +
            "}";


}

4.4 总结

五、JavaRestClient(文档)

5.1 使用Java客户端示例:

示例代码:

复制代码
package com.etc.search;

import org.apache.http.HttpHost;

import org.bouncycastle.cert.ocsp.Req;
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;

@SpringBootTest
class TripSearchApplicationTests {

    private RestHighLevelClient client;

    @Test
    void testConnection() {
        System.out.println("client: "+client);
    }


    private static final String DOCUMENT_TEMPLATE = "{\n" +
            "  \"id\":\"1\",\n" +
            "  \"name\":\"csh\",\n" +
            "  \"price\":\"11\"\n" +
            "}";

    @Test
    void testCreateDocument() throws IOException{
        IndexRequest request = new IndexRequest("items").id("1");
        request.source(DOCUMENT_TEMPLATE,XContentType.JSON);
        client.index(request,RequestOptions.DEFAULT);
    }


    @Test
    void testDeleteDocument() throws IOException{
        DeleteRequest request = new DeleteRequest("items","1");

        client.delete(request,RequestOptions.DEFAULT);
    }

    @Test
    void testGetDocument() throws IOException{
        GetRequest request = new GetRequest("items","1");
        GetResponse response =  client.get(request, RequestOptions.DEFAULT);
        String json = response.getSourceAsString();
        System.out.println(json);
    }

    @Test
    void testUpdateDocument() throws IOException{
        UpdateRequest request = new UpdateRequest("items","1");
        request.doc(
                "name","csh2024",
                "price",2024
        );
        client.update(request,RequestOptions.DEFAULT);
    }

    @BeforeEach
    void setUp(){
        client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.92.136:9200")
        ));
    }

    @AfterEach
    void tearDown() throws IOException{
        if(client != null){
            client.close();
        }
    }



}

5.2 文档批量操作

5.3 总结:

六、DSL查询

6.1 DSL查询介绍

6.2 DSL查询所有

6.3 DSL叶子查询

match查询单个字段,需要更改key和value的值,而multi_match查询多个字段,key值无需改变。

6.4 复合查询

6.4.1 复合查询的bool查询

6.4.2 复合查询的排序和分页

示例:先按照销量降序排列,若销量一直则按升序排列

复制代码
GET /items/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "sold": {
        "order": "desc"
      }, 
      "price": {
        "order": "asc"
      }
    }
  ]
}

from的计算公式:(页数-1)*页条;

ES对from和size进行限制,两者相加不能超过10000

6.5 高亮

6.6 搜索总结

七、JavaRestClient (搜索)

7.1 查询所有

示例:查询所有(match_all)

复制代码
package com.etc.search;

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.QueryBuilders;
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 TripSearchApplicationTests {

    private RestHighLevelClient client;

    @Test
    void testMatchAll() throws IOException{
        SearchRequest request = new SearchRequest("items");

        request.source()
                .query(QueryBuilders.matchAllQuery());

        SearchResponse response = client.search(request,RequestOptions.DEFAULT);
        System.out.println("response = "+ response);
    }


    @BeforeEach
    void setUp(){
        client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.92.136:9200")
        ));
    }

    @AfterEach
    void tearDown() throws IOException{
        if(client != null){
            client.close();
        }
    }



}

7.2 解析查询结果

7.3 构建查询条件

7.3.1 构建查询条件(matchQuery,multiMatchQuery)

7.3.2 构建查询条件(termQuery,rangeQuery)

7.3.3 构建查询条件(bool查询)

示例:使用JavaRestClient实现以下的搜索:

  • 搜索关键字为脱脂牛奶
  • 品牌为德亚
  • 价格必须低于300

代码:

复制代码
package com.etc.search;

import net.minidev.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.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
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 TripSearchApplicationTests {

    private RestHighLevelClient client;

    @Test
    void testSearch() throws IOException{
        SearchRequest request = new SearchRequest("items");

        request.source()
                .query(QueryBuilders.boolQuery()
                        .must(QueryBuilders.matchQuery("name","脱脂牛奶"))
                        .filter(QueryBuilders.termQuery("brand","德亚"))
                        .filter(QueryBuilders.rangeQuery("price").lt(300)));

        SearchResponse response = client.search(request,RequestOptions.DEFAULT);

        parseResponseResult(response);


    }

    private static void parseResponseResult(SearchResponse response) {
        //总条数
        SearchHits searchHits = response.getHits();
        long total = searchHits.getTotalHits().value;
        System.out.println("total = "+total);
        //命中条数
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit: hits){
            String json = hit.getSourceAsString();

            System.out.println("doc = "+ json);
        }
    }


    @BeforeEach
    void setUp(){
        client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.92.136:9200")
        ));
    }

    @AfterEach
    void tearDown() throws IOException{
        if(client != null){
            client.close();
        }
    }



}

7.3.4 排序和分页

7.4 高亮

高亮显示结果解析

示例:解析结果方法

复制代码
private static void parseResponseResult(SearchResponse response) {
        //总条数
        SearchHits searchHits = response.getHits();
        long total = searchHits.getTotalHits().value;
        System.out.println("total = "+total);
        //命中条数
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit: hits){
            String json = hit.getSourceAsString();
            
            //转换为ItemDoc
            ItemDoc doc = JSONUtil.toBean(json,ItemDoc.class);
            
            //处理高亮结果
            Map<String, HighlightField> hfs = hit.getHighlightFields();
            if(hfs != null && !hfs.isEmpty()){
                HighlightField hf = hfs.get("name");
                String hfName = hf.getFragments()[0].string();
                doc.setName(hfName);
            }
            System.out.println("doc = "+ doc);
        }
    }

八、数据聚合

8.1 数据聚合的介绍

注意:参与聚合的字段必须是Keyword、数值、日期、布尔类型的字段

8.2 DSL聚合

8.3 JavaRestClient数据聚合

复制代码
package com.etc.search;

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.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;

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.util.List;
import java.util.Map;

@SpringBootTest
class TripSearchApplicationTests {

    private RestHighLevelClient client;

    @Test
    void testAgg() throws IOException{
        SearchRequest request = new SearchRequest("items");

        request.source().size(0);

        String brandAggName  = "brandAgg";

        request.source().aggregation(
                AggregationBuilders.terms(brandAggName).field("brand").size(10)
        );

        SearchResponse response = client.search(request,RequestOptions.DEFAULT);

        Aggregations aggregations = response.getAggregations();

        Terms brandTerms  = aggregations.get(brandAggName);

        List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();

        for (Terms.Bucket bucket :buckets){
            System.out.println("brand: "+bucket.getKeyAsString());
            System.out.println("count: "+bucket.getDocCount());
        }
    }

    @BeforeEach
    void setUp(){
        client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.92.136:9200")
        ));
    }

    @AfterEach
    void tearDown() throws IOException{
        if(client != null){
            client.close();
        }
    }



}
相关推荐
独自破碎E15 分钟前
Java是怎么实现跨平台的?
java·开发语言
To Be Clean Coder22 分钟前
【Spring源码】从源码倒看Spring用法(二)
java·后端·spring
xdpcxq102941 分钟前
风控场景下超高并发频次计算服务
java·服务器·网络
想用offer打牌44 分钟前
你真的懂Thread.currentThread().interrupt()吗?
java·后端·架构
橘色的狸花猫1 小时前
简历与岗位要求相似度分析系统
java·nlp
独自破碎E1 小时前
Leetcode1438绝对值不超过限制的最长连续子数组
java·开发语言·算法
用户91743965391 小时前
Elasticsearch Percolate Query使用优化案例-从2000到500ms
java·大数据·elasticsearch
计算机毕设VX:Fegn08951 小时前
计算机毕业设计|基于springboot + vue小区人脸识别门禁系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
yaoxin5211232 小时前
279. Java Stream API - Stream 拼接的两种方式:concat() vs flatMap()
java·开发语言
wang_yb2 小时前
格式塔原理:数据可视化如何引导观众的注意力
大数据·databook