Chiriri's blog Chiriri's blog
首页
  • Java

    • JavaSE
    • JavaEE
    • 设计模式
  • Python

    • Python
    • Python模块
    • 机器学习
  • Golang

    • Golang
    • gRPC
  • 服务器

    • Linux
    • MySQL
    • NoSQL
    • Kubernetes
  • 项目

    • 传智健康
    • 畅购商城
  • Hadoop生态

    • Hadoop
    • Zookeeper
    • Hive
    • Flume
    • Kafka
    • Azkaban
    • Hbase
    • Scala
    • Spark
    • Flink
  • 大数据项目

    • 离线数仓
  • 青训营

    • 第四届青训营
  • HTML

    • HTML
    • JavaScript
  • Vue

    • Vue2
    • TypeScript
    • Vue3
    • Uni-APP
  • 数据结构与算法
  • C语言
  • 考研数据结构
  • 计算机组成原理
  • 计算机操作系统
  • Java基础

    • Java基础
    • Java集合
    • JUC
    • JVM
  • 框架

    • Spring
    • Dubbo
    • Spring Cloud
  • 数据库

    • MySQL
    • Redis
    • Elasticesearch
  • 消息队列

    • RabbitMQ
    • RocketMQ
  • 408

    • 计算机网络
    • 操作系统
    • 算法
  • 分类
  • 标签
  • 归档
  • 导航站
GitHub (opens new window)

Iekr

苦逼后端开发
首页
  • Java

    • JavaSE
    • JavaEE
    • 设计模式
  • Python

    • Python
    • Python模块
    • 机器学习
  • Golang

    • Golang
    • gRPC
  • 服务器

    • Linux
    • MySQL
    • NoSQL
    • Kubernetes
  • 项目

    • 传智健康
    • 畅购商城
  • Hadoop生态

    • Hadoop
    • Zookeeper
    • Hive
    • Flume
    • Kafka
    • Azkaban
    • Hbase
    • Scala
    • Spark
    • Flink
  • 大数据项目

    • 离线数仓
  • 青训营

    • 第四届青训营
  • HTML

    • HTML
    • JavaScript
  • Vue

    • Vue2
    • TypeScript
    • Vue3
    • Uni-APP
  • 数据结构与算法
  • C语言
  • 考研数据结构
  • 计算机组成原理
  • 计算机操作系统
  • Java基础

    • Java基础
    • Java集合
    • JUC
    • JVM
  • 框架

    • Spring
    • Dubbo
    • Spring Cloud
  • 数据库

    • MySQL
    • Redis
    • Elasticesearch
  • 消息队列

    • RabbitMQ
    • RocketMQ
  • 408

    • 计算机网络
    • 操作系统
    • 算法
  • 分类
  • 标签
  • 归档
  • 导航站
GitHub (opens new window)
  • JavaSE

  • JavaEE

    • MyBatis
    • Jackson
    • Jedis
    • Maven
    • POI
    • Spring
    • Spring MVC
    • Maven 高级
    • Dubbo
    • Zookeeper
    • Spring Security
    • Spring Boot
    • Spring Boot 高级
    • RabbitMQ
    • RabbitMQ 高级
    • Spring Cloud
    • Docker
    • ElasticSearch
      • 倒排索引
      • ElasticSearch搜索和传统数据库查询的区别
      • 安装ElasticSearch
        • 安装辅助工具Kibana
      • ElasticSearch 核心概念
      • 操作ElasticSearch
        • RESTful风格
        • 操作索引
        • 添加索引
        • 查询索引
        • 删除索引
        • 关闭指定索引
        • 操作映射
        • 添加映射
        • 操作文档
      • 分词器
      • IK分词器
        • 安装
        • 使用
        • 查询文档
      • JavaApi
        • 添加索引
        • 查询索引
        • 删除索引
        • 判断索引是否存在
        • 添加/修改文档
        • Map
        • JSON
        • 查询文档
        • 删除文档
    • ElasticSearch 高级
  • Linux

  • MySQL

  • NoSQL

  • Python

  • Python模块

  • 机器学习

  • 设计模式

  • 传智健康

  • 畅购商城

  • 博客项目

  • JVM

  • JUC

  • Golang

  • Kubernetes

  • 硅谷课堂

  • C

  • 源码

  • 神领物流

  • RocketMQ

  • 短链平台

  • 后端
  • JavaEE
Iekr
2021-10-07
目录

ElasticSearch

# ElasticSearch

ElasticSearch 是基于 Lucene 的搜索服务器 是一个分布式 高扩展 高实时的搜索与数据分析引擎

基于 RESTful web 接口

ElasticSearch 是用 java 开发 并作为 apache 的开源项目

https://www.elastic.co/cn/

一般用于 海量数据的查询 日志数据分析 实时数据分析

# 倒排索引

将各个文档中内容。进行分词 形成词条 记录词条和数据的唯一标识 (id) 的对应关系 形成的产物

# ElasticSearch 搜索和传统数据库查询的区别

  1. 传统关系型数据 使用模糊查询 左边有通配符 不会走索引 会全表扫描 性能低
  2. 只能以一个关键字作为查询条件 而 ElasticSearch 会把一个关键字拆分为多个词 进行查询
  3. ElasticSearch 以关键字 生成的倒排索引 词条会排序 形成一颗树形结构 提升词条的查询速度
  4. Mysql 有事务性 而 ElasticSearch 没有事务性 所以删了的数据是无法恢复的
  5. ElasticSearch 没有物理外键这个特性 如果数据的一致性要求比较高 不建议使用
  6. ElasticSearch 和 Mysql 分工不同 Mysql 负责存储数据 ElasticSearch 负责搜索数据

# 安装 ElasticSearch

tar -zxvf elasticsearch-7.15.0-linux-x86_64.tar.gz -C /opt
#编辑配置
vim /opt/elasticsearch-7.15.0/config/elasticsearch.yml

#追加以下内容
cluster.name: my-application
node.name: node-1
network.host: 0.0.0.0
http.port: 9200
cluster.initial_master_nodes: ["node-1"]

#出于安全问题ElasticSearch不允许root用户直接运行
useradd iekr
passwd 123456
#授权
chown -R iekr:iekr /opt/elasticsearch-7.15.0/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

新建的用户最大创建文件和最大虚拟内存太小 需要修改配置文件

#修改最大创建文件数
vim /etc/security/limits.conf

#追加内容
iekr soft nofile 65536
iekr hard nofile 65536

vim /etc/security/limits.d/20-nproc.conf
#追加内容
iekr soft nofile 65536
iekr hard nofile 65536
* hard nproc 4096


#修改虚拟内容大小
vim /etc/sysctl.conf 

#追加内容
vm.max_map_count=655360
#重载
sysctl -p

firewall-cmd --zone=public --add-port=9200/tcp --permanent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

启动

su iekr
cd /opt/elasticsearch-7.15.0/bin/
./elasticsearch -d  #-d后台运行
1
2
3

访问 http://192.168.130.124:9200/ 出现 json 字符串则启动成功

# 安装辅助工具 Kibana

https://www.elastic.co/cn/kibana/

tar -zxvf kibana-7.15.0-linux-x86_64.tar.gz -C /opt
#配置
vim /opt/kibana-7.15.0-linux-x86_64/config/kibana.yml

#追加内容
server.port: 5601
server.host: "0.0.0.0"
server.name: "your-hostname"  #自定义名称
elasticsearch.hosts: ["http://localhost:9200"]
elasticsearch.requestTimeout: 30000  #连接ES超时时间
i18n.locale: "zh-CN"  #设置为中文

#授权
chown -R iekr:iekr /opt/kibana-7.15.0-linux-x86_64/
firewall-cmd --zone=public --add-port=5601/tcp --permanent
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

启动

su iekr
cd /opt/kibana-7.15.0-linux-x86_64/bin/
nohup ./kibana &  #后台运行  前台./kibana
1
2
3

# ElasticSearch 核心概念

  • 索引 (index) ElasticSearch 存储数据的地方 可以理解为关系型数据库中的数据库概念

  • 映射 (mapping)

    mapping 定义了每个字段的类型 字段所使用的分词器等 相定义关系型数据库中的表结构

  • 文档 (document) ElasticSearch 中的最小数据单元 以 json 格式显示 一个 document 相当于 关系型数据库的一行数据

  • 倒排索引 一个倒排索引由文档中所有不重复此的列表构成 对应其中每个词 对应一个包含它的文档 id 列表

  • 类型 (type)

    一种 type 就像一类表 如用户表 角色表等 在 ElasticSearch7.x type 默认为_doc

    5.x 中一个 index 可以有多种 type

    6.x 中一个 index 只能有一种 type

# 操作 ElasticSearch

# RESTful 风格

REST 表述性状态转移 是一组架构约束条件和原则 满足这些约束条件和原则的应用程序或设计就是 RESTful 是与只能怪定义接口的规范

# 操作索引

以下操作使用 postman 工具发送请求

# 添加索引

使用 PUT 请求 在 uri 地址后加上索引名称

192.168.130.124:9200/goods_index
1

# 查询索引

使用 GET 请求 在 uri 地址后加上索引名称

192.168.130.124:9200/goods_index
1

查询多个使用逗号分隔

192.168.130.124:9200/goods_index,goods_index2
1

查询全部使用_all

192.168.130.124:9200/_all
1

# 删除索引

使用 DELETE 请求 在 uri 地址后加上索引名称

192.168.130.124:9200/goods_index
1

# 关闭指定索引

关闭后只是无法使用 并不会删除此索引

192.168.130.124:9200/goods_index/_close
1

打开索引

192.168.130.124:9200/goods_index/_open
1

# 操作映射

  • 简单数据类型
    • 字符串
      • text 会分词,不支持聚合
      • keyword 不会分词 将全部内容作为一个词条 支持聚合
    • 数组
    • 布尔
    • 二进制
      • binary
    • 范围类型
      • integer_range
      • float_range
      • long_range
      • double_range
      • date_range
    • 日期
  • 复杂数据类型
    • 数组:[]
    • 对象:{}

# 添加映射

以下操作使用 Kibana 操作

http://192.168.130.124:5601/app/dev_tools#/console

# 创建索引
PUT person
# 查询索引
GET person

# 添加映射
PUT person/_mapping
{
  "properties":{
    "name":{
      "type":"keyword"
    },
    "age":{
      "type":"integer"
    }
  }
}

# 查询映射
GET person/_mapping

# 删除索引
DELETE person

# 创建索引并添加映射
PUT person
{
  "mappings": {
    "properties": {
        "name":{
      "type":"keyword"
    },
    "age":{
      "type":"integer"
    }
    }
  }
}

# 查询索引
GET person

# 添加字段
PUT person/_mapping
{
  "properties":{
    "address":{
      "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
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

# 操作文档

# 查询索引
GET person


# 添加文档 指定id   可以使用PUT或POST请求
PUT person/_doc/1
{
  "name":"zhangsan",
  "age":20,
  "address":"北京"
}


# 添加文档 不指定id  必须为POST请求
POST person/_doc
{
  "name":"李四",
  "age":30,
  "address":"广东"
}


# 根据id查询文档
GET person/_doc/1


# 查询所有文档
GET person/_search

# 修改文档   必须为PUT请求  如果id存在则修改 不存在则自动创建
PUT person/_doc/1
{
  "name":"wangwu",
  "age":20,
  "address":"北京"
}

# 根据ID删除文档
DELETE person/_doc/1
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

# 分词器

image-20211007015716324

但 ES 原始的分词器对中文不太友好

# IK 分词器

IKAnalyzer 是一个开源的 基于 java 语言开发的轻量级的中文分词工具包

是一个基于 Maven 构建的项目 具有 60 万字 / 秒的高速处理能力 支持用户词典扩展定义

https://github.com/medcl/elasticsearch-analysis-ik

# 安装

  • 安装 JDK 由于 ES 内置了 JDK 我们将 ES 内置的 JDK 设置为系统环境变量
vim /etc/profile

export JAVA_HOME=/opt/elasticsearch-7.15.0/jdk
export PATH=$PATH:${JAVA_HOME}/bin

source /etc/profile
1
2
3
4
5
6
  • 安装 Maven -- 已不需要
wget https://mirrors.bfsu.edu.cn/apache/maven/maven-3/3.8.3/binaries/apache-maven-3.8.3-bin.tar.gz
tar -zxvf apache-maven-3.8.3-bin.tar.gz
ln -s apache-maven-3.8.3 maven
#配置环境变量
vim /etc/profile.d/maven.sh

export MAVEN_HOME=/root/maven
export PATH=${MAVEN_HOME}/bin:${PATH}

source /etc/profile.d/maven.sh
mvn -v
1
2
3
4
5
6
7
8
9
10
11
  • 安装 IK 分词器 -- 已不需要
wget https://github.com/medcl/elasticsearch-analysis-ik/archive/refs/tags/v7.15.0.zip  #这里下载的是源码
# 由于是zip文件所以需要unzip命令
yum install -y zip
yum install -y unzip
#解压
unzip v7.15.0.zip

cd /root/elasticsearch-analysis-ik-7.15.0/
#编译打包
mvn package
1
2
3
4
5
6
7
8
9
10
  • 将编译好的插件导入到 ES 中
cd /opt/elasticsearch-7.15.0/plugins/
mkdir analysis-ik
cd analysis-ik/
#重启es

1
2
3
4
5

# 使用


# ES内置分词器
GET _analyze
{
  "analyzer": "standard",
  "text": "你是试试水"
}

# ik分词器,粗粒度分词
GET _analyze
{
  "analyzer": "ik_smart",
  "text": "你是试试水"
}

# ik分词器,粗粒度分词
GET _analyze
{
  "analyzer": "ik_max_word",
  "text": "你是试试水"
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 查询文档

  • 词条查询:tern
    • 词条查询不会分析查询条件 只有当词条和查询字符串完全匹配时才匹配搜索
  • 全文查询:match
    • 全文查询会分析查询条件 先将查询条件进行分词 然后查询 求并集
PUT person/_doc/2
{
  "name":"李四",
  "age":30,
  "address":"华为5G手机"
}

GET person/_doc/2

# term 词条查询 查询条件字符串和词条要完全匹配
# es默认使用的分词器是standard 一个子一个词
GET person/_search
{
  "query":{
    "term": {
      "address": {
        "value": "手机"
      }
    }
  }
}

DELETE person

# 创建索引 添加映射 指定使用ik分词器
PUT person
{
  "mappings": {
    "properties": {
      "name":{
        "type": "keyword"
      },
      "address":{
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

GET person

# 添加文档
PUT person/_doc/1
{
  "name":"张三",
  "age":30,
  "address":"华为5G手机"
}
PUT person/_doc/2
{
  "name":"李四",
  "age":30,
  "address":"广东"
}
PUT person/_doc/3
{
  "name":"王五",
  "age":30,
  "address":"小米5G手机"
}

GET person/_search

# 查询 term词条查询
GET person/_search
{
  "query":{
    "term": {
      "address": {
        "value": "手机"
      }
    }
  }
}

# match 先会对查询的字符串进行分词 在查询 求交集
GET person/_search
{
  "query": {
    "match": {
      "address": "苹果手机"
    }
  }
}

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

# JavaApi

  1. 创建 springboot 项目 并引入 ES

    image-20211007152049832

  2. 创建 application.yml 配置文件

    elasticsearch:
      host: 192.168.130.124
      port: 9200
    
    1
    2
    3
  3. 创建 ElasticSearchConfig 配置类 加载配置文件 并返回一个 es 客户端对象

    package com.itheima.elasticsearchdemo.config;
    
    
    import org.apache.http.HttpHost;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @ConfigurationProperties(prefix = "elasticsearch")
    public class ElasticSearchConfig {
    
        private String host;
        private int port;
    
        public String getHost() {
            return host;
        }
    
        public void setHost(String host) {
            this.host = host;
        }
    
        public int getPort() {
            return port;
        }
    
        public void setPort(int port) {
            this.port = port;
        }
    
        @Bean
        public RestHighLevelClient client(){
            return new RestHighLevelClient(RestClient.builder(
                    new HttpHost(host,port,"http")
            ));
    
        }
    }
    
    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
  4. 注入对象 使用

    //1.创建es客户端对象
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    
    1
    2
    3

# 添加索引

//添加索引
@Test
void addIndex() throws IOException {
    //获取操作索引的对象
    IndicesClient indices = restHighLevelClient.indices();
    //添加
    CreateIndexRequest createIndex = new CreateIndexRequest("itheima");  //索引名称
    CreateIndexResponse createIndexResponse = indices.create(createIndex, RequestOptions.DEFAULT);
    //根据返回值判断结果
    System.out.println(createIndexResponse.isAcknowledged());
}
1
2
3
4
5
6
7
8
9
10
11
  • 添加索引并添加映射
//添加索引并添加映射
@Test
void addIndexAndMapping() throws IOException {
    //获取操作索引的对象
    IndicesClient indices = restHighLevelClient.indices();
    CreateIndexRequest request = new CreateIndexRequest("twitter");

    // 向索引添加映射
    request.source("{\n" +
            "    \"settings\" : {\n" +
            "        \"number_of_shards\" : 3,\n" +
            "        \"number_of_replicas\" : 2\n" +
            "    },\n" +
            "    \"mappings\" : {\n" +
            "        \"tweet\" : {\n" +
            "            \"properties\" : {\n" +
            "                \"message\" : { \"type\" : \"text\" }\n" +
            "            }\n" +
            "        }\n" +
            "    },\n" +
            "    \"aliases\" : {\n" +
            "        \"twitter_alias\" : {}\n" +
            "    }\n" +
            "}", XContentType.JSON);
    CreateIndexResponse createIndexResponse = indices.create(request, RequestOptions.DEFAULT);
    //根据返回值判断结果
    System.out.println(createIndexResponse.isAcknowledged());
}
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

# 查询索引

//查询索引
@Test
public void queryIndex() throws IOException {
    GetIndexRequest request = new GetIndexRequest("twitter");
    GetIndexResponse getIndexResponse = restHighLevelClient.indices().get(request, RequestOptions.DEFAULT);
    System.out.println(getIndexResponse.getAliases());
    System.out.println(getIndexResponse.getMappings());
}
1
2
3
4
5
6
7
8

# 删除索引

//删除索引
@Test
public void deleteIndex() throws IOException {
    IndicesClient indices = restHighLevelClient.indices();
    DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("itheima");
    AcknowledgedResponse acknowledgedResponse = indices.delete(deleteIndexRequest, RequestOptions.DEFAULT);
    System.out.println(acknowledgedResponse.isAcknowledged());
}
1
2
3
4
5
6
7
8

# 判断索引是否存在

//判断索引是否存在
@Test
public void existIndex() throws IOException {
    IndicesClient indices = restHighLevelClient.indices();
    GetIndexRequest getRequest = new GetIndexRequest("itheima");
    boolean exists = indices.exists(getRequest, RequestOptions.DEFAULT);
    System.out.println(exists);

}
1
2
3
4
5
6
7
8
9

# 添加 / 修改文档

当 id 存在时则修改 不存在时则添加

# Map

//添加/修改 map
@Test
public void addDoc() throws IOException {
    //添加数据对象 map
    Map<String, String> data = new HashMap<>();
    data.put("address","背景");
    data.put("name","钻石");
    data.put("age","11");
    //1.获取文档对象
    IndexRequest indexRequest = new IndexRequest("twitter").id("1").source(data);
    //添加数据
    IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
    //打印响应结果
    System.out.println(index.getId());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# JSON

//添加/修改 json
@Test
public void addDoc2() throws IOException {
   //创建对象
    Person p =new Person();
    p.setId("2");
    p.setName("iekr");
    p.setAge(15);
    p.setAddress("广东");
    String json = JSON.toJSONString(p);
    //1.获取文档对象
    IndexRequest indexRequest = new IndexRequest("twitter").id(p.getId()).source(json,XContentType.JSON);
    //添加数据
    IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
    //打印响应结果
    System.out.println(index.getId());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 查询文档

    //根据id查询文档
    @Test
    public void findDocById() throws IOException {
        GetRequest getRequest = new GetRequest("twitter", "1");
//        getRequest.id("1");  //单独指定id
        GetResponse documentFields = restHighLevelClient.get(getRequest, RequestOptions.DEFAULT);
        System.out.println(documentFields.getSourceAsString()); //获取JSON字符串

    }
1
2
3
4
5
6
7
8
9

# 删除文档

//根据id删除文档
@Test
public void delDoc() throws IOException {
    DeleteRequest delete = new DeleteRequest("twitter", "1");
    DeleteResponse response = restHighLevelClient.delete(delete, RequestOptions.DEFAULT);
    System.out.println(response.getId()); 

}
1
2
3
4
5
6
7
8
编辑 (opens new window)
上次更新: 2023/12/06, 01:31:48
Docker
ElasticSearch 高级

← Docker ElasticSearch 高级→

最近更新
01
k8s
06-06
02
进程与线程
03-04
03
计算机操作系统概述
02-26
更多文章>
Theme by Vdoing | Copyright © 2022-2025 Iekr | Blog
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式