ElasticSearch-1
原文链接:https://gaoyubo.cn/blogs/52ef5bf7.html
一、Elasticsearch 架构设计
Elasticsearch 架构层:

Elasticsearch 五层架构设计图:

说明:
- Elasticsearch是基于Lucene架构实现的,所以其核心层为Lucene
- Elasticsearch 目前支持HTTP、Thrift、Memcache三种协议,默认是HTTP
- JMX指在Elasticsearch中对 Java 的管理架构,用来管理Elasticsearch应用
二、Docker部署
2.1加载es镜像
因为我们还需要部署kibana容器,因此需要让es和kibana容器互联。这里先创建一个网络:
docker network create es-net
# 导入数据
docker load -i es.tar
同理还有kibana的tar包也需要这样做。
# 导入数据
docker load -i kibana.tar
2.2运行镜像
docker run -d \
--name es \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
-e "discovery.type=single-node" \
-v es-data:/usr/share/elasticsearch/data \
-v es-plugins:/usr/share/elasticsearch/plugins \
--privileged \
--network es-net \
-p 9200:9200 \
-p 9300:9300 \
elasticsearch:7.12.1
-e "cluster.name=es-docker-cluster":设置集群名称-e "http.host=0.0.0.0":监听的地址,可以外网访问-e "ES_JAVA_OPTS=-Xms512m -Xmx512m":内存大小-e "discovery.type=single-node":非集群模式-v es-data:/usr/share/elasticsearch/data:挂载逻辑卷,绑定es的数据目录-v es-logs:/usr/share/elasticsearch/logs:挂载逻辑卷,绑定es的日志目录-v es-plugins:/usr/share/elasticsearch/plugins:挂载逻辑卷,绑定es的插件目录--privileged:授予逻辑卷访问权--network es-net:加入一个名为es-net的网络中-p 9200:9200:端口映射配置
此时访问9200端口,可以访问到已经部署成功

2.3部署kibana
kibana可以提供一个elasticsearch的可视化界面
docker run -d \
--name kibana \
-e ELASTICSEARCH_HOSTS=http://es:9200 \
--network=es-net \
-p 5601:5601 \
kibana:7.12.1
--network es-net:加入一个名为es-net的网络中,与elasticsearch在同一个网络中-e ELASTICSEARCH_HOSTS=http://es:9200":设置elasticsearch的地址,因为kibana已经与elasticsearch在一个网络,因此可以用容器名直接访问elasticsearch-p 5601:5601:端口映射配置
部署成功

2.4离线安装ik插件
查看数据卷目录
安装插件需要知道elasticsearch的plugins目录位置,而我们用了数据卷挂载,因此需要查看elasticsearch的数据卷目录,通过下面命令查看:
docker volume inspect es-plugins

说明plugins目录被挂载到了:/var/lib/docker/volumes/es-plugins/_data 这个目录中。
上传插件


# 重启容器
docker restart es
# 查看es日志
docker logs -f es
扩展词词典
词汇需要不断的更新,IK分词器提供了扩展词汇的功能。
1)打开IK分词器config目录:

2)在IKAnalyzer.cfg.xml配置文件内容添加:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 *** 添加扩展词典-->
<entry key="ext_dict">ext.dic</entry>
</properties>
3)新建一个 ext.dic,可以参考config目录下复制一个配置文件进行修改
奥力给
4)重启elasticsearch
docker restart es
日志中已经成功加载ext.dic配置文件
注意当前文件的编码必须是 UTF-8 格式,严禁使用Windows记事本编辑
三、索引库操作
3.1创建索引库
索引库就类似数据库表,mapping映射就类似表的结构。
基本语法:
- 请求方式:PUT
- 请求路径:/索引库名,可以自定义
- 请求参数:mapping映射
PUT /index1
{
"mappings": {
"properties": {
"info": {
"type": "text",
"analyzer": "ik_smart"
},
"email": {
"type": "keyword",
"index": false
},
"name": {
"type": "object",
"properties": {
"firstName": {
"type": "keyword"
},
"lastName": {
"type": "keyword"
}
}
}
}
}
}

3.2查询索引库
基本语法:
请求方式:GET
请求路径:/索引库名
请求参数:无

3.3修改索引库
倒排索引结构虽然不复杂,但是一旦数据结构改变(比如改变了分词器),就需要重新创建倒排索引。因此索引库一旦创建,无法修改mapping。
虽然无法修改mapping中已有的字段,但是却允许添加新的字段到mapping中,因为不会对倒排索引产生影响。
语法说明:
PUT /索引库名/_mapping
{
"properties": {
"新字段名":{
"type": "integer"
}
}
}


四、文档操作
4.1添加文档
POST /索引库名/_doc/文档id
{
"字段1": "值1",
"字段2": "值2",
"字段3": {
"子属性1": "值3",
"子属性2": "值4"
},
// ...
}

4.2查询文档
语法:
GET /{索引库名称}/_doc/{id}

4.3.删除文档
删除使用DELETE请求,同样,需要根据id进行删除:
语法:
DELETE /{索引库名}/_doc/id值
4.4修改文档
修改有两种方式:
- 全量修改:直接覆盖原来的文档
- 增量修改:修改文档中的部分字段
全量修改
全量修改是覆盖原来的文档,其本质是:
- 根据指定的id删除文档
- 新增一个相同id的文档
类似于Java中的HashMap的put操作
PUT /{索引库名}/_doc/文档id
{
"字段1": "值1",
"字段2": "值2",
// ... 略
}

增量修改
增量修改是只修改指定id匹配的文档中的部分字段。
语法:
POST /{索引库名}/_update/文档id
{
"doc": {
"字段名": "新的值",
}
}

五、RestAPI操作索引库
其中的Java Rest Client又包括两种:
- Java Low Level Rest Client
- Java High Level Rest Client

译文:
Java底层REST客户端:Elasticsearch的官方底层客户端。它允许通过http与Elasticsearch集群通信。将请求编组和响应反编组留给用户。它与所有Elasticsearch版本兼容。
Java高级REST客户端:Elasticsearch的官方高级客户端。基于底层客户端,它公开了特定于API的方法,并负责请求编组和响应反编组。
我们学习的是Java HighLevel Rest Client客户端API
mapping映射分析
创建索引库,最关键的是mapping映射,而mapping映射要考虑的信息包括:
- 字段名
- 字段数据类型
- 是否参与搜索
- 是否需要分词
- 如果分词,分词器是什么?
其中:
- 字段名、字段数据类型,可以参考数据表结构的名称和类型
- 是否参与搜索要分析业务来判断,例如图片地址,就无需参与搜索
- 是否分词呢要看内容,内容如果是一个整体就无需分词,反之则要分词
- 分词器,我们可以统一使用ik_max_word
- id主键特殊,不实用long,而是使用keyword
MySQL数据结构如下:
CREATE TABLE `tb_hotel` (
`id` bigint(20) NOT NULL COMMENT '酒店id',
`name` varchar(255) NOT NULL COMMENT '酒店名称;例:7天酒店',
`address` varchar(255) NOT NULL COMMENT '酒店地址;例:航头路',
`price` int(10) NOT NULL COMMENT '酒店价格;例:329',
`score` int(2) NOT NULL COMMENT '酒店评分;例:45,就是4.5分',
`brand` varchar(32) NOT NULL COMMENT '酒店品牌;例:如家',
`city` varchar(32) NOT NULL COMMENT '所在城市;例:上海',
`star_name` varchar(16) DEFAULT NULL COMMENT '酒店星级,从低到高分别是:1星到5星,1钻到5钻',
`business` varchar(255) DEFAULT NULL COMMENT '商圈;例:虹桥',
`latitude` varchar(32) NOT NULL COMMENT '纬度;例:31.2497',
`longitude` varchar(32) NOT NULL COMMENT '经度;例:120.3925',
`pic` varchar(255) DEFAULT NULL COMMENT '酒店图片;例:/img/1.jpg',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
根据MySQL表结构构造了如下的mapping映射
PUT /hotel
{
"mappings": {
"properties": {
"id": {
"type": "keyword"
},
"name":{
"type": "text",
"analyzer": "ik_max_word",
"copy_to": "all"
},
"address":{
"type": "keyword",
"index": false
},
"price":{
"type": "integer"
},
"score":{
"type": "integer"
},
"brand":{
"type": "keyword",
"copy_to": "all"
},
"city":{
"type": "keyword",
"copy_to": "all"
},
"starName":{
"type": "keyword"
},
"business":{
"type": "keyword"
},
"location":{
"type": "geo_point"
},
"pic":{
"type": "keyword",
"index": false
},
"all":{
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
此时会发现多出一个all字段:因为如果很多字段都需要倒排索引,那么性能就会下降,ES可以使用cpoy_to属性将当前字段拷贝到指定字段,在指定字段里,统一构造倒排索引。

location:地理坐标,里面包含精度、纬度

初始化RestClient
- 引入es的RestHighLevelClient依赖:
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
<properties>
<java.version>1.8</java.version>
<elasticsearch.version>7.12.1</elasticsearch.version>
</properties>

因为SpringBoot进行了自动依赖管理,默认的ES版本是7.6.2,所以需要额外指定固定版本。
- 初始化RestHighLevelClient:
初始化的代码如下:
RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://xxx:9200")
));

创建索引库
@Test
void hotelIndexCreate() throws IOException {
//获取create请求
CreateIndexRequest createIndexRequest = new CreateIndexRequest("hotel");
//添加请求参数
createIndexRequest.source(ESTemplate.CreateHotelTemplate(), XContentType.JSON);
//发送请求
client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
}

添加请求参数时的json语句,就是dev Tools中编写的json语句
删除索引库
@Test
void testDeleteHotelIndex() throws IOException {
// 1.创建Request对象
DeleteIndexRequest request = new DeleteIndexRequest("hotel");
// 2.发送请求
client.indices().delete(request, RequestOptions.DEFAULT);
}
判断索引库是否存在
@Test
void testExistsHotelIndex() throws IOException {
// 1.创建Request对象
GetIndexRequest request = new GetIndexRequest("hotel");
// 2.发送请求
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
// 3.输出
System.err.println(exists ? "索引库已经存在!" : "索引库不存在!");
}
索引库操作的基本步骤:
- 初始化RestHighLevelClient
- 创建XxxIndexRequest。XXX是Create、Get、Delete
- 准备DSL( Create时需要,其它是无参)
- 发送请求。调用RestHighLevelClient#indices().xxx()方法,xxx是create、exists、delete
六、RestAPI操作文档
添加文档
@Test
void hotelDocCreate() throws IOException {
//获取mysql表hotel记录
Hotel hotel = hotelService.getById(36934L);
//转化为doc
HotelDoc hotelDoc = new HotelDoc(hotel);
//获取create请求
IndexRequest request = new IndexRequest("hotel" ).id(hotelDoc.getId().toString());
//添加请求参数
request.source(JSON.toJSONString(hotelDoc),XContentType.JSON);
//发送请求(文档操作,不需要indices)
client.index(request,RequestOptions.DEFAULT);
}

查询文档
@Test
void testGetDocumentById() throws IOException {
// 1.准备Request
GetRequest request = new GetRequest("hotel", "36934");
// 2.发送请求,得到响应
GetResponse response = client.get(request, RequestOptions.DEFAULT);
// 3.解析响应结果
String json = response.getSourceAsString();
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
System.out.println(hotelDoc);
}

修改文档
- 全量修改:本质是先根据id删除,再新增
- 增量修改:修改文档中的指定字段值
在RestClient的API中,全量修改与新增的API完全一致,判断依据是ID:
- 如果新增时,ID已经存在,则修改
- 如果新增时,ID不存在,则新增
@Test
void testUpdateDocument() throws IOException {
// 1.准备Request
UpdateRequest request = new UpdateRequest("hotel", "36934");
// 2.准备请求参数
request.doc(
"price", "100000000",
"starName", "四钻"
);
// 3.发送请求
client.update(request, RequestOptions.DEFAULT);
}
删除文档
@Test
void testDeleteDocument() throws IOException {
// 1.准备Request
DeleteRequest request = new DeleteRequest("hotel", "61083");
// 2.发送请求
client.delete(request, RequestOptions.DEFAULT);
}
批量添加文档
步骤如下:
- 利用mybatis-plus查询酒店数据
- 将查询到的酒店数据(Hotel)转换为文档类型数据(HotelDoc)
- 利用JavaRestClient中的BulkRequest批处理,实现批量新增文档
@Test
void testBulkRequest() throws IOException {
// 批量查询酒店数据
List hotels = hotelService.list();
// 1.创建Request
BulkRequest request = new BulkRequest();
// 2.准备参数,添加多个新增的Request
for (Hotel hotel : hotels) {
// 2.1.转换为文档类型HotelDoc
HotelDoc hotelDoc = new HotelDoc(hotel);
// 2.2.创建新增文档的Request对象
request.add(new IndexRequest("hotel")
.id(hotelDoc.getId().toString())
.source(JSON.toJSONString(hotelDoc), XContentType.JSON));
}
// 3.发送请求
client.bulk(request, RequestOptions.DEFAULT);
}
ElasticSearch-1的更多相关文章
- Elasticsearch之java的基本操作一
摘要 接触ElasticSearch已经有一段了.在这期间,遇到很多问题,但在最后自己的不断探索下解决了这些问题.看到网上或多或少的都有一些介绍ElasticSearch相关知识的文档,但个人觉得 ...
- Elasticsearch 5.0 中term 查询和match 查询的认识
Elasticsearch 5.0 关于term query和match query的认识 一.基本情况 前言:term query和match query牵扯的东西比较多,例如分词器.mapping ...
- 以bank account 数据为例,认识elasticsearch query 和 filter
Elasticsearch 查询语言(Query DSL)认识(一) 一.基本认识 查询子句的行为取决于 query context filter context 也就是执行的是查询(query)还是 ...
- Ubuntu 14.04中Elasticsearch集群配置
Ubuntu 14.04中Elasticsearch集群配置 前言:本文可用于elasticsearch集群搭建参考.细分为elasticsearch.yml配置和系统配置 达到的目的:各台机器配置成 ...
- ElasticSearch 5学习(10)——结构化查询(包括新特性)
之前我们所有的查询都属于命令行查询,但是不利于复杂的查询,而且一般在项目开发中不使用命令行查询方式,只有在调试测试时使用简单命令行查询,但是,如果想要善用搜索,我们必须使用请求体查询(request ...
- ElasticSearch 5学习(9)——映射和分析(string类型废弃)
在ElasticSearch中,存入文档的内容类似于传统数据每个字段一样,都会有一个指定的属性,为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成字符串值,Elasticsearc ...
- .net Elasticsearch 学习入门笔记
一. es安装相关1.elasticsearch安装 运行http://localhost:9200/2.head插件3.bigdesk插件安装(安装细节百度:windows elasticsear ...
- 自己写的数据交换工具——从Oracle到Elasticsearch
先说说需求的背景,由于业务数据都在Oracle数据库中,想要对它进行数据的分析会非常非常慢,用传统的数据仓库-->数据集市这种方式,集市层表会非常大,查询的时候如果再做一些group的操作,一个 ...
- 如何在Elasticsearch中安装中文分词器(IK+pinyin)
如果直接使用Elasticsearch的朋友在处理中文内容的搜索时,肯定会遇到很尴尬的问题--中文词语被分成了一个一个的汉字,当用Kibana作图的时候,按照term来分组,结果一个汉字被分成了一组. ...
- jar hell & elasticsearch ik 版本问题
想给es 安装一个ik 的插件, 我的es 是 2.4.0, 下载了一个版本是 1.9.5, [2016-10-09 16:56:26,248][INFO ][node ] [node-2] init ...
随机推荐
- Django框架——模型层单表操作、模型层多表操作、模型层常用和非常用字段和参数、模型层进阶
文章目录 1 模型层-单表操作 一 ORM简介 二 单表操作 2.1 创建表 1 创建模型 2 更多字段 3 更多参数 4 settings配置 5 增加,删除字段 2.2 添加表纪录 2.3 查询表 ...
- MySQL系列之读写分离架构——Atlas介绍、安装配置、Atlas功能测试、生产用户要求、Atlas基本管理、自动分表、关于读写分离建议
文章目录 1. Atlas介绍 2.安装配置 3. Atlas功能测试 4. 生产用户要求 5. Atlas基本管理 6. 自动分表 7. 关于读写分离建议 1. Atlas介绍 Atlas是由 Qi ...
- 基于Java Swing和BouncyCastle的证书生成工具
"Almost no one will remember what he had just not interested." - Nobody "几乎没有人会记得他所丝毫 ...
- Python 环境迁移
平时用python环境会装一堆依赖,也包括自己的模块,要迁移到陌生环境,得好好处理才行. 下面介绍个方法,实践过还可以: 总结下步骤: miniconda或conda安装一个python环境,pyth ...
- Godot - 创建翻译文件(常量表)
版本 Godot 3.1.2 背景 Godot的UI系统封装的很难受, 一些东西很难改动, 比如这个AcceptDialog的"确定""取消"按钮, 特别是在编 ...
- alibaba fastjson的JsonObject有序的实现和源码分析
介绍 FastJson是阿里巴巴的开源JSON解析库,它可以解析JSON格式的字符串,支持将Java Bean序列化为JSON字符串,也可以从JSON字符串反序列化到JavaBean.在使用的过程中, ...
- 监控报警体系:Prometheus和Grafana
总体 prometheus全链路监控报警,在当今云原生时代可观测领域,Prometheus + Grafana 成为可观测性事实标准. 采集数据:运维团队可以使用 Prometheus 监控云原生 K ...
- 设置Eclipse自动补全变量名
具体配置步骤如下: Windows -> Preferences -> Java -> Editor -> Content Assist 选中 Enable auto-acti ...
- [Python急救站]草莓熊的绘制
草莓熊也是一个热门的图案,今天就用Python绘制一下 import turtle as t # 设置背景颜色,窗口位置以及大小 t.colormode(255) # 颜色模式 t.speed(0) ...
- Educational Codeforces Round 127 (Rated for Div. 2) E. Preorder
设\(f[v]\)是以结点\(v\)为根的方案数,设左子树的根为\(x\),右子树的根为\(y\),那么如果左右子树完全相同,那么我们交换左右子树对方案没有任何影响,都是: \[f[v] = f[x] ...