Elaticsearch

11/15/2022 后端
(adsbygoogle = window.adsbygoogle || []).push({});

# 简介

分布式实时搜索和分析引擎,处理PB级别的结构化或非结构化数据

# 基本概念

文档型数据库,用JSON作为文档序列化的格式 索引对应数据库概念 可以用JAVA api,也可以用HTTP请求操作

# 安装

elasticsearch-7.15.2 bin目录下双击bat脚本 可视客户端kibana 默认英语 kibana-7.15.2-windows-x86_64\config\kibana.yml 末尾添加 i18n.locale: "zh-CN" bin目录下启动 打开后台url http://127.0.0.1:5601/app/home#/ 开发工具运行即可 image

# 索引(表)操作

分片 提高吞吐量

查看es中的索引: GET /_cat/indices?v 结果展示的数据量是准确的

# 创建索引:

PUT /索引名 PUT /products

PUT /products1 { "settings": { "number_of_shards": 1, #指定主分片数量 "number_of_replicas": 1 #指定副本分片数量 } } ES中索引健康状态,red(索引不可用),yellow(索引可用,存在风险),green(健康)

创建索引时候,一并创建映射: 常见类型: 字符串类型:keyword(关键词关键字,精确匹配支持排序,不能模糊分词查询)、text(一段文本,可以分词查询) 数字类型:integer log 小数类型:float double 布尔类型:boolean 日期类型:date

ElasticSearch是不允许修改字段的type类型的

PUT /products
{
  "settings": {
    "number_of_replicas": 0,
    "number_of_shards": 1
  },
  "mappings": {
    "properties": {
      "id":{
        "type":"integer"
      },
      "title":{
        "type":"keyword"
      },
      "price":{
        "type":"double"
      },
      "create_at":{
        "type":"date"
      },
      "description":{
        "type":"text"
      }
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 删除索引:

DELETE /products

# 查询索引映射信息(表结构):

GET /索引名/_mapping GET /products/_mapping

文档操作:Json格式

# 文档(数据)操作

# 添加文档操作

1、指定ID POST /products/_doc/1 { "id":1, "title":"薯条", "price":"10.5", "create_at":"2022-04-30", "description":"薯条真好吃啊" }

不指定ID POST /products/_doc/ { "title":"辣条", "price":"9.5", "create_at":"2022-04-30", "description":"辣条真是辣两头啊" }

# 查询

totol里面 gte表示大于等于10000条 手动指定文档id查询:

GET /products/_doc/1
GET /products/_doc/4LPib4QBFlEnOmw2wIAG
1
2

查看所有文档

GET /products/_search
{
  "query": {
    "match_all": {}
  }
}

1
2
3
4
5
6
7

查询结果












 
 











































































{
   "took": 13,
   "timed_out": false,
   "_shards": {
       "total": 1,
       "successful": 1,
       "skipped": 0,
       "failed": 0
   },
   "hits": {
       "total": {
           "value": 10000,
           "relation": "gte"
       },
       "max_score": null,
       "hits": [
           {
               "_index": "products",
               "_type": "_doc",
               "_id": "1107405",
               "_score": null,
               "_source": {
                   "_class": "com.zr.vo.Product",
                   "id": "1107405",
                   "title": "107403羔廓忆恒",
                   "price": 0.0,
                   "create_at": "2022-11-28",
                   "description": "豆丈虞玛娇瞬惦略哥策涎蛊街一狄顿拇笋隅芬硕香"
               },
               "sort": [
                   0.0
               ]
           },
           {
               "_index": "products",
               "_type": "_doc",
               "_id": "1912893",
               "_score": null,
               "_source": {
                   "_class": "com.zr.vo.Product",
                   "id": "1912893",
                   "title": "912891凤",
                   "price": 0.0,
                   "create_at": "2022-11-29",
                   "description": "虎一暖腔延方宵慕镇稽联丝坟痒"
               },
               "sort": [
                   0.0
               ]
           },
           {
               "_index": "products",
               "_type": "_doc",
               "_id": "1058849",
               "_score": null,
               "_source": {
                   "_class": "com.zr.vo.Product",
                   "id": "1058849",
                   "title": "58847属纱剧供",
                   "price": 0.01,
                   "create_at": "2022-11-14",
                   "description": "筒硷氟粪谦片列呛逐夜"
               },
               "sort": [
                   0.01
               ]
           },
           {
               "_index": "products",
               "_type": "_doc",
               "_id": "1069141",
               "_score": null,
               "_source": {
                   "_class": "com.zr.vo.Product",
                   "id": "1069141",
                   "title": "69139嫌包澎",
                   "price": 0.03,
                   "create_at": "2022-11-19",
                   "description": "窒否矫修痊署鳖片伪荷退巾码墅吁彬翔全北橱厩泡村轻胁"
               },
               "sort": [
                   0.03
               ]
           }
       ]
   }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

# 删除文档(行)

根据ID 条件删除

POST products/_delete_by_query
{
  "query": {
    "match": {
      "title":"辣条"
    }
  }
}
1
2
3
4
5
6
7
8

# 更新文档(行)

POST /products/_doc/1/_update
{
  "doc":{
    "price":"5.8",
    "title":"薯条"
  }
}
1
2
3
4
5
6
7

# 与spring boot集成

添加配置类

package com.zr.config;

import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;

@Configuration
public class ElasticsearchConfig {
    @Bean
    RestHighLevelClient elasticsearchClient() {
        ClientConfiguration configuration = ClientConfiguration.builder()
                .connectedTo("127.0.0.1:9200")
                .build();
        RestHighLevelClient client = RestClients.create(configuration).rest();
        return client;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

注意:ID要使用String,日期要使用String 因为id如果没指定会随机生成类似"CJY5eoQBBwK1xW0ZOt5M"的

package com.zr.vo;

import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;

@Document(indexName = "products")
public class Product {

    private  String id;

    private String title;

    private double price;

    @Field(name = "create_at")
    private String createAt;

    private String description;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getCreateAt() {
        return createAt;
    }

    public void setCreateAt(String createAt) {
        this.createAt = createAt;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

# 原生的查询方法

//条件查询,可以组合下面的查询 should() == or; must()== and //QueryBuilders.boolQuery()

# 精确查询 =

QueryBuilders.termQuery()

@RequestMapping("/createAt")
public String createAt( String data) throws IOException {
    //创建请求
    SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.termQuery("create_at",data))
    //分页
    .from(0).size(10)
    .sort("price", SortOrder.ASC);
    Long s =System.currentTimeMillis();
    SearchRequest searchRequest = new SearchRequest("products");
    searchRequest.source(builder);
    //执行请求
    SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
    Long e = System.currentTimeMillis();
    System.out.println(e-s);

    CountRequest countRequest = new CountRequest("products");
    countRequest.source(builder);
    CountResponse countResponse = client.count(countRequest, RequestOptions.DEFAULT);

    System.out.println(countResponse.toString());

    return response.toString();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 模糊查询,会分词 like

QueryBuilders.matchQuery() 不分词查询的方法: QueryBuilders.matchPhraseQuery()

    @RequestMapping("/description")
    public String description( String data) throws IOException {
        //创建请求
        SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchQuery("description",data))
                //分页
                .from(0).size(10)
                .sort("price", SortOrder.ASC);
        Long s =System.currentTimeMillis();
        SearchRequest searchRequest = new SearchRequest("products");
        searchRequest.source(builder);
        //执行请求
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        Long e = System.currentTimeMillis();
        System.out.println(e-s);

        CountRequest countRequest = new CountRequest("products");
        countRequest.source(builder);
        CountResponse countResponse = client.count(countRequest, RequestOptions.DEFAULT);
        System.out.println(countResponse.toString());

        return response.toString();
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 高亮显示

HighlightBuilder highlightBuilder = new HighlightBuilder();
  highlightBuilder.requireFieldMatch(false)//因为高亮查询默认是对查询字段即description就行高亮,可以关闭字段匹配,这样就可以对查询到的多个字段(前提是有关键词并且改字段可以分词)进行高亮显示
          .field("description")//若有关键字切可以分词,则可以高亮,写*可以匹配所有字段
          .field("title")//若有关键字切可以分词,则可以高亮,写*可以匹配所有字段
          .preTags("<span style='color:red;'>")//手动前缀标签
          .postTags("</span>");

SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchPhraseQuery("description",data))
              //分页
              .from(0).size(10)
              .sort("price", SortOrder.ASC)
              .highlighter(highlightBuilder);
1
2
3
4
5
6
7
8
9
10
11
12

返回的JSON多了highlight,里面有设置的span标签

{
    "took": 9,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 5485,
            "relation": "eq"
        },
        "max_score": null,
        "hits": [
            {
                "_index": "products",
                "_type": "_doc",
                "_id": "1519801",
                "_score": null,
                "_source": {
                    "_class": "com.zr.vo.Product",
                    "id": "1519801",
                    "title": "519799腊",
                    "price": 0.02,
                    "create_at": "2022-11-21",
                    "description": "敌孙饱斑潘买哎欲膏赛良身析簿靶冈恶宇麻寒震赴小"
                },
                "highlight": {
                    "description": [
                        "敌孙饱斑<span style='color:red;'>潘</span>买哎欲膏赛良身析簿靶冈恶宇麻寒震赴小"
                    ]
                },
                "sort": [
                    0.02
                ]
            },
            {
                "_index": "products",
                "_type": "_doc",
                "_id": "1323841",
                "_score": null,
                "_source": {
                    "_class": "com.zr.vo.Product",
                    "id": "1323841",
                    "title": "323839陀",
                    "price": 0.05,
                    "create_at": "2022-11-06",
                    "description": "遣呕慨右致眶禽客与刘隋喘屏仅戍芹潘池蜂"
                },
                "highlight": {
                    "description": [
                        "遣呕慨右致眶禽客与刘隋喘屏仅戍芹<span style='color:red;'>潘</span>池蜂"
                    ]
                },
                "sort": [
                    0.05
                ]
            },
            {
                "_index": "products",
                "_type": "_doc",
                "_id": "1861508",
                "_score": null,
                "_source": {
                    "_class": "com.zr.vo.Product",
                    "id": "1861508",
                    "title": "861506舍伦越寂",
                    "price": 0.05,
                    "create_at": "2022-11-28",
                    "description": "痹硕柳雹云藕济茫哆硼励突孪沟斤间札央栏僵沛挡潘誊含"
                },
                "highlight": {
                    "description": [
                        "痹硕柳雹云藕济茫哆硼励突孪沟斤间札央栏僵沛挡<span style='color:red;'>潘</span>誊含"
                    ]
                },
                "sort": [
                    0.05
                ]
            }
        ]
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

也可以直接替换"_source"下的"description"

# 范围查询 between and

QueryBuilders.rangeQuery()

# 参考

https://www.cnblogs.com/morehair/p/15823879.html https://my.oschina.net/fusublog/blog/3050964

我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=38dpnhkh4o8wo