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



}
相关推荐
孤水寒月22 分钟前
Git忽略文件.gitignore
git·elasticsearch
田猿笔记23 分钟前
Typesense:开源的高速搜索引擎
搜索引擎
wm104327 分钟前
java web springboot
java·spring boot·后端
smile-yan28 分钟前
Provides transitive vulnerable dependency maven 提示依赖存在漏洞问题的解决方法
java·maven
老马啸西风29 分钟前
NLP 中文拼写检测纠正论文-01-介绍了SIGHAN 2015 包括任务描述,数据准备, 绩效指标和评估结果
java
Earnest~32 分钟前
Maven极简安装&配置-241223
java·maven
皮蛋很白35 分钟前
Maven 环境变量 MAVEN_HOME 和 M2_HOME 区别以及 IDEA 修改 Maven repository 路径全局
java·maven·intellij-idea
青年有志37 分钟前
JavaWeb(一) | 基本概念(web服务器、Tomcat、HTTP、Maven)、Servlet 简介
java·web
上海研博数据41 分钟前
flink+kafka实现流数据处理学习
java
KpLn_HJL43 分钟前
leetcode - 2139. Minimum Moves to Reach Target Score
java·数据结构·leetcode