分布式搜索引擎,可以用来实现搜索、日志统计、分析、系统监控等功能倒排索引什么是文档和词条?
正向索引?文档id创建索引。查询词条时必须先找到文档,而后判断是否包含词条倒排索引?词条创建索引,并记录词条所在文档的id信息。查询时先根据词条查询到文档id,而后根据文档id获取到文档。elasticsearch是面向文档储存的,文档数据会被序列化为json格式后储存在elasticsearch中。
文档的集合字段约束信息,类似表的结构约束
因为还需要部署kibana容器,因此需要让es和kibana容器互联。先创建一个网路
dockerhub地址:https://hub.docker.com/_/elasticsearch
docker network create es-net
docker pull elasticsearch:7.12.1
docker pull kibana:7.12.1
这里如果拉取失败,可以尝试重启dockerdocker load -i elasticsearch.tar
docker load -i kibana.tar
docker run -d
--name elasticsearch # 容器名
-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
--net es-net # 加入创建的网络
-p 9200:9200 # 用户访问的端口
-p 9300:9300 # 容器互联访问的端口
elasticsearch:7.12.1
docker run -d
--name kibana
-e ELASTICSEARCH_HOSTS=http://elasticsearch:9200 #同一个网络可以使用容器名代替IP
--network=es-net #加入创建的网络
-p 5601:5601
kibana:7.12.1 # tag要和es一致
version : '3'
#networks:
# es:
services:
elasticsearch:
container_name: elasticsearch
image: elasticsearch:7.12.1
ports:
- 9200:9200
- 9300:9300
volumes:
- ./es-data:/usr/share/elasticsearch/data
- ./es-plugins:/usr/share/elasticsearch/plugins
environment:
ES_JAVA_OPTS: -Xms512m -Xmx512m
discovery.type: single-node
privileged: true
# networks:
# - "es"
kinana:
container_name: kinana
image: kibana:7.12.1
ports:
- 5601:5601
# networks:
# - "es"
environment:
ELASTICSEARCH_HOSTS: http://elasticsearch:9200
# volumes:
# - ./kibana.yml:/usr/share/kibana/config/kibana.yml



# 进入容器内部
docker exec -it elasticsearch /bin/bash
# 在线下载并安装
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.12.1/elasticsearch-analysis-ik-7.12.1.zip
# 退出
exit
#重启容器
docker restart elasticsearch
IK分词器包含两种模式:
ik_smart: 最少切分
ik_max_word:最细切分

DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置comment>
<entry key="ext_dict">ext.dicentry>
<entry key="ext_stopwords">stopword.dicentry>
properties>


mapping是对索引库中文档的约束,常见的mapping属性包括:
type:字段数据类型,常见的简单类型有:index:是否创建索引,默认为true(创建倒排索引,参与搜索)、false(不创建倒排索引,不参与搜索)。analyzer:使用哪种分词器properties:该字段的子字段类似mysql的表
# 新建
PUT /mytable
{
"mappings": {
"properties": {
"info": {
"type": "text",
"analyzer": "ik_smart"
},
"email": {
"type": "keyword",
"index": false
},
"name": {
"type": "object",
"properties": {
"firstName": {
"type": "keyword"
},
"lastName": {
"type": "keyword"
}
}
}
}
}
}
GET /索引库名
DELETE /索引库名
PUT /索引库名/_mapping
{
"properties": {
"新字段名": {
"type": "integer"
}
}
}
举例如下:
# 查询
GET /mytable
# 修改
PUT /mytable/_mapping
{
"properties":{
"age": {
"type": "integer"
}
}
}
# 删除
DELETE /mytable
POST /索引库名/_doc/文档id
{
"info": "奥特曼来自M78星云",
"email": "302976975@qq.com",
"name": {
"firstName": "迪",
"lastName": "迦"
}
}
举个例子:
# 插入文档
POST /mytable/_doc/1
{
"info": "奥特曼来自M78星云",
"email": "302976975@qq.com",
"name": {
"firstName": "迪",
"lastName": "迦"
}
}
GET /索引库名/_doc/文档id
举个例子:
GET /mytable/_doc/1
DELETE /索引库名/_doc/文档id
举个例子:
DELETE /mytable/_doc/1
PUT /索引库名/_doc/文档id
{
"info": "奥特曼来自M78星云",
"email": "302976975@qq.com",
"name": {
"firstName": "迪",
"lastName": "迦"
}
}
举个例子:
# 全量修改文档
PUT /mytable/_doc/1
{
"info": "奥特曼来自M78星云",
"email": "302976975@qq.com",
"name": {
"firstName": "赛",
"lastName": "罗"
}
}
POST /索引库名/_update/文档id
{
"doc": {
"info": "赛罗奥特曼来自M78星云"
}
}
举个例子:
# 增量修改
POST /mytable/_update/1
{
"doc": {
"info": "赛罗奥特曼来自M78星云"
}
}
PUT /patient
{
"mappings": {
"properties": {
"patientId": {
"type": "keyword",
"copy_to": "all"
},
"barCode": {
"type": "keyword",
"copy_to": "all"
},
"barCodeImage": {
"type": "keyword",
"index": false
},
"patientName": {
"type": "text",
"analyzer": "ik_max_word",
"copy_to": "all"
},
"patientAge": {
"type": "integer",
"copy_to": "all"
},
"patientSex": {
"type": "keyword",
"copy_to": "all"
},
"hospitalNum": {
"type": "keyword",
"copy_to": "all"
},
"opcNum": {
"type": "keyword",
"copy_to": "all"
},
"abo": {
"type": "keyword"
},
"rh": {
"type": "keyword"
},
"irregular": {
"type": "keyword"
},
"reportPath": {
"type": "keyword",
"index": false
},
"reportStatus": {
"type": "keyword"
},
"createTime": {
"type": "date",
"copy_to": "all"
},
"updateTime": {
"type": "date",
"index": false
},
"deleteTime": {
"type": "date"
},
"remark": {
"type": "text",
"analyzer": "ik_max_word",
"copy_to": "all"
},
"all": {
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
注意:版本要一致!!!
<dependency>
<groupId>org.elasticsearch.clientgroupId>
<artifactId>elasticsearch-rest-high-level-clientartifactId>
<version>7.12.1version>
dependency>
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 java.io.IOException;
public class EsTest {
private RestHighLevelClient client;
@Test
public void test(){
System.out.println(client);
}
@BeforeEach
public void testBefor(){
this.client = new RestHighLevelClient(
RestClient.builder(
//可以是多个
HttpHost.create("http://127.0.0.1:9200")
)
);
}
@AfterEach
public void testAfter() throws IOException {
this.client.close();
}
}
@Test
public void createPatientIndex() throws IOException {
// 1 创建Request对象,命名索引库名称
CreateIndexRequest request = new CreateIndexRequest("patient");
// 2 请求参数,内容是DSL语句的json字符串,类型json
request.source(MAPPING_TEMPLATE, XContentType.JSON);
// 3 发起请求
client.indices().create(request, RequestOptions.DEFAULT);
}
@Test
public void deletePatientIndex() throws IOException {
// 1 创建Request对象,命名索引库名称
DeleteIndexRequest request = new DeleteIndexRequest("patient");
// 2 发起请求
client.indices().delete(request, RequestOptions.DEFAULT);
}
@Test
public void existsPatientIndex() throws IOException {
// 1 创建Request对象,命名索引库名称
GetIndexRequest request = new GetIndexRequest("patient");
// 2 发起请求
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
}
@Test
public void addDoc() throws IOException {
FangzhouUser fangzhouUser = fangzhouUserMapper.selectFangzhouUserByPatientId(1l);
// 1 准备Request对象
IndexRequest indexRequest = new IndexRequest("patient").id(fangzhouUser.getPatientId().toString());
// 2 准备json文档
indexRequest.source(JSON.toJSONString(fangzhouUser),XContentType.JSON);
// 3 发起请求
client.index(indexRequest,RequestOptions.DEFAULT);
}
@Test
public void testSelectDoc() throws IOException {
// 1.准备Request
GetRequest request = new GetRequest("patient", "1");
// 2.发送请求,得到相应
GetResponse response = client.get(request, RequestOptions.DEFAULT);
// 3.解析相应结果
String jsonstr = response.getSourceAsString();
FangzhouUser fangzhouUser = JSON.parseObject(jsonstr, FangzhouUser.class);
System.out.println(fangzhouUser);
}
@Test
public void testUpdateDoc() throws IOException {
UpdateRequest request = new UpdateRequest("patient", "1");
request.doc(
"patientName","胡云峰",
"patientSex","女"
);
client.update(request,RequestOptions.DEFAULT);
}
@Test
public void testDeleteDoc() throws IOException {
DeleteRequest request = new DeleteRequest("patient", "1");
client.delete(request,RequestOptions.DEFAULT);
}
@Test
public void testBulkDoc() throws IOException {
List<FangzhouUser> userList = fangzhouUserMapper.selectFangzhouUserList(new FangzhouUser());
BulkRequest bulkRequest = new BulkRequest();
for (FangzhouUser user : userList) {
bulkRequest.add(new IndexRequest("patient").id(user.getPatientId().toString()).source(JSON.toJSONString(user),XContentType.JSON));
}
client.bulk(bulkRequest,RequestOptions.DEFAULT);
}