ElasticSearch(ES)
文章目录
- 备注、必看
- ElasticSearch 和 Solr 介绍,对比
- ElasticSearch 7.8.
- 官网
- 基本概念
- Cluster(集群) 与 Node(节点)
- Index -索引
- 索引结构
- 索引原理:Inverted Index(倒排索引)
- 索引分片
- Type(逐渐弃用)
- Document -文档
- 文档结构
- 节点用法:冷热数据分离
- http操作ES
- 集群 操作
- 索引 操作
- 索引-映射 操作
- 文档 操作 CRUD
- !!!查询
- 查询语法 Query DSL
- 多索引查询
- 统计总数据条数
- 插件:IK中文分词器
- 分词器字典
- 分词算法
- 工具
- 1. 可视化工具 ElasticSearch-head
- 2. 数据分析展示 Kibana
- springboot集成
- TransportClient
- RestClient
备注、必看
文章背景:
之前没接触过搜索引擎,然后接手了一个es的项目,临时抱佛脚东拼西凑查资料把项目支持下去了,把过程中查的资料与自己的一些操作整理了一下发了出来
不适合新人入门学习,也不适合专家参考
,
如果你也是被迫从都不知道搜索引擎就要在项目快速使用es,那可以快速的过一遍本文有个基础的使用概念
ElasticSearch 和 Solr 介绍,对比
- ElasticSearch和Solr 都是封装了
Lucene
; 实现全文搜索
功能
ElasticSearch
- 解压即用
- 提供RESTful API接口,只支持json
- 注重核心的搜索功能,在处理大数据时性能更好
- 刚兴起,更新快
Solr
- 安装稍微复杂
- 提供类似 webservice的API接口,支持json,xml,csv
- 有很多额外的功能,适合传统搜索
- 使用成熟,用户多
ElasticSearch 7.8.
官网
https://www.elastic.co/cn/elasticsearch/
- 学习网站
https://www.knowledgedict.com/tutorial/elasticsearch-intro.html
基本概念
关系型数据库与ElasticSearch对比
向Elasticsearch中存储数据,其实就是向es中的index下面的type中存储json类型的数据。
Cluster(集群) 与 Node(节点)
Elastic 本质上是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个 Elastic 实例。
单个 Elastic 实例称为一个节点(node)。
一组节点构成一个集群(cluster)。
- 主节点
- 数据节点
- 客户端节点
Index -索引
- Elastic 数据管理的顶层单位就叫做 Index(索引), 含义类似单个数据库
- Index (即数据库)的名字必须是小写。
索引结构
- aliases
- mappings 映射,定义type
- settings
{"users" : {"aliases" : { 别名 },"mappings" : {type-name : {"properties" : {"age" : {"type" : "integer"},"name" : {"type" : "keyword"}}}},"settings" : { 索引设置 }}
}
索引原理:Inverted Index(倒排索引)
- Elastic 会索引所有字段,经过处理后写入一个Inverted Index
- 通过文档内容去管理主键ID
- 可以过滤无关数据,提高效率,适用于快速全文搜索
索引:通过有序的key去找value
正排索引
:key=文档,value=关键词
倒排索引
:key=关键词,value=文档
索引分片
单个节点由于物理机硬件限制 大小是有限的。一个索引如果特别大 导致在单个节点放不下。
索引分成多个分片,分片可以存储在集群中不同节点
- 主分片
分片并非将所有的数据都放在一起,多个主分片合起来才是所有的数据
以默认的5个主分片为例,ES会将数据均衡的存储到5个分片上,
也就是这5个分片的数据并集才是整个数据集,
这5个分片会按照一定规则分配到不同的ES Node上。这样的5个分片叫主分片。
- 从分片
从分片只是主分片的一个副本,它用于提供数据的冗余副本
默认设置是一个主分片会有一个从分片,那么就有5个从分片,那么默认配置会产生10个分片(5主5从)就散布在所有的Node上
Type(逐渐弃用)
用来定义数据结构
- 例:该type 有age和name两个字段,age字段是integer类型,name是keyword类型
type-name : {"properties" : {"age" : {"type" : "integer"},"name" : {"type" : "keyword"}}}
- 用法:
- 一个索引 里 有多种type,就可以存储多种类型的数据
- 多个索引里有同一种 type,可以只根据type全部查询出来
5.x 支持多种type
6.x 只能有一种type
7.x 版本基本不用
8.x 版本舍弃
Document -文档
- Index 里面单条的记录称为 Document(文档)
- 使用 JSON 格式表示
- 搜索数据的最小单元
文档结构
{"_index": 所属索引,"_type": 所属type,"_id": 唯一id,"_version": 版本,"_score": 相关度评分,"_source": {"name": "张三","age": "18"}
}
节点用法:冷热数据分离
https://blog.csdn.net/laoyang360/article/details/102539888
http操作ES
集群 操作
查看集群信息
- GET http://IP:9200/
{"name": "eZ3dEvq","cluster_name": "ElasticSearch","cluster_uuid": "唯一id","version": {"number": "5.5.3","build_hash": "9305a5e","build_date": "2017-09-07T15:56:59.599Z","build_snapshot": false,"lucene_version": "6.6.0"},"tagline": "You Know, for Search"
}
索引 操作
method | url | 作用 |
---|---|---|
PUT | http://IP:9200/{索引名称} | 创建索引 |
GET | http://IP:9200/_cat/indices?v | 查看所有索引 |
GET | http://IP:9200/{索引名称} | 查看单个索引 |
DELETE | http://IP:9200/{索引名称} | 删除索引 |
{".kibana"【索引名】: {"aliases"【别名】: {},"mappings"【映射 mappings信息 :修改字段和类型】: {"timelion-sheet":{}},"settings"【settings信息 :修改分片和副本数】: {"index"【索引】: {"creation_date"【创建时间】: "1614265373911","number_of_shards"【主分片数量】: "1","number_of_replicas"【副分片数量】: "1","mapper": {"dynamic": "false"},"provided_name"【名称】: ".kibana""uuid"【唯一标识】: "eI5wemRERTumxGCc1bAk2A","version"【版本】: {"created": "7080099"}}}}
}
索引-映射 操作
- 创建映射
curl -X PUT 'IP:9200/shopping/_mapping' -d '
{"properties": {"字段名":{"type": " 类型 :字符串/数字/日期/数组/对象【text、keyword(不可分词)、long、short、date、integer、Array、object】","index": 是否索引【是索引就可以用来进行搜索】,"store": false,【是否将数据进行独立存储】,"analyzer": "分词器"},"name":{"type": "text","index": true},"sex":{"type": "text","index": false},"age":{"type": "long","index": false}}
}'
文档 操作 CRUD
method | url | 作用 |
---|---|---|
POST | http://IP:9200/{索引名称}/{文档名称} | 创建文档(随机id) |
POST | http://IP:9200/{索引名称}/{文档名称}/{id} | 创建文档(指定id) |
GET | http://IP:9200/{索引名称}/{文档名称}/{id} | 查看文档 |
POST | http://IP:9200/{索引名称}/{文档名称}/{id} | 更新文档=创建覆盖文档 |
POST | http://IP:9200/{索引名称}/{文档名称}/{id}/_update | 更新字段 |
DELETE | http://IP:9200/{索引名称}/{文档名称}/{id} | 删除文档 |
POST | http://IP:9200/{索引名称}/_delete_by_query | 条件删除文档 |
- 创建文档
curl -X POST 'IP:9200/shopping/phone' -d '
{"title":"小米手机","category":"小米10","price":3999.00
}'
# 服务器响应结果
{"_index"【索引】: "shopping","_type"【 类型-文档 】: "phone","_id"【唯一标识】: "Xhsa2ncBlvF_7lxyCE9G", #可以类比为 MySQL 中的主键,随机生成"_version"【版本】: 1,"result"【结果】: "created", #这里的 create 表示创建成功"_shards"【分片】: {"total"【分片 - 总数】: 2,"successful"【分片 - 成功】: 1,"failed"【分片 - 失败】: 0},"_seq_no": 0,"_primary_term": 1
}
- 更新字段:单价改为4000
curl -X POST 'IP:9200/shopping/phone/Xhsa2ncBlvF_7lxyCE9G/_update' -d '
{"doc": {"price":4000.00}
}'
- 删除指定id的文档
curl -X DELETE 'IP:9200/shopping/phone/{id}'
- 条件删除文档:删除单价为4000的文档
curl -X POST 'IP:9200/shopping/phone/_delete_by_query' -d '
{"query":{"match":{"price":4000.00}}
}'
!!!查询
查询语法 Query DSL
以 _search 为endpoint,主要分为字段类查询和复合查询。
- 字段类查询:只针对某一个字段进行查询,如match、term等;
- 单词匹配:不进行分词处理,直接匹配
- 全文匹配:先对查询语句进行分词处理,然后再去匹配
- 复合查询:可以进行一个或多个字段的查询,如bool查询等.
POST /_search
{"query":{"查询类型":{"查询条件":"查询条件值"}}
}
查询类型包括
- 全文匹配
- match_all 查询所有
- match 匹配查询
- multi_match 多字段匹配查询
- match_phrase 有顺序要求
- query_string
- simple_query_string
- 单词匹配
- term 不分词
- terms
- range 用于date或number类型的字段范围查询
- 复合查询、组合查询
- bool
- must 返回的文档必须满足must子句的条件,并且参与计算分值
- must_not 返回的文档必须不满足定义的条件
- filter 返回的文档必须满足filter子句的条件, 不计算分值
- should 如果没有must或者filter,有一个或者多个should子句,那么只要满足一个就可以返回
- bool
搜索案例详见 :
https://blog.csdn.net/xyc1211/article/details/120349794
多索引查询
一个索引可以接受多个 alias 别名,而一个别名也可以映射到多个索引
索引1,索引2
统计总数据条数
GET /{index}/_count
插件:IK中文分词器
https://github.com/medcl/elasticsearch-analysis-ik
作用:把一段中文,按照分词器字典,拆分成一个个关键词
使用方法:
下载解压ik,放在es的plugins目录下,启动es会自动加载ik插件
分词器字典
默认字典:ik/config/*.dic
可以在 ik/config/IKAnalyzer.cfg.xml
文件 配置扩展字典
分词算法
- ik_smart 最少切分
- ik_max_word 最细粒度划分
curl -X PUT 'localhost:9200/accounts' -d '
{"mappings": {"person": {"properties": {"desc": {"type": "张三是谁啊","analyzer": "ik_max_word","search_analyzer": "ik_smart"}}}}
}'
- analyzer:字段文本的分词器
- search_analyzer:搜索词的分词器
工具
1. 可视化工具 ElasticSearch-head
https://github.com/mikewuhao/es-head
安装
- 可以独立安装使用(需要前端npm环境)
- 也可以通过浏览器插件使用
使用
- 连接es集群,可以 查看集群中的索引,索引中的类型,类型中的字段
- 查看文档
- 查询搜索
- 连接es集群,可以 查看集群中的索引,索引中的类型,类型中的字段
2. 数据分析展示 Kibana
https://blog.csdn.net/xyc1211/article/details/117397854
springboot集成
es官网也提供了ES Java RestClient的方式来访问es
<!-- es --><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>5.5.3</version></dependency><!-- es 客户端 --><dependency><groupId>org.elasticsearch.client</groupId><artifactId>rest</artifactId><version>5.5.3</version></dependency>
Elasticsearch(ES)有两种连接方式:
- TransportClient
- RestClient。
都是线程安全的,都应该使用单例。
TransportClient
- 通过TCP方式访问ES
- 该transport node并不会加入集群,而是简单的向ElasticSearch集群上的节点发送请求。
- 只支持java
- Elasticsearch计划在Elasticsearch 7.0中弃用TransportClient,在8.0中完全删除
import java.net.InetAddress;import org.elasticsearch.action.get.GetResponse;import org.elasticsearch.client.transport.TransportClient;import org.elasticsearch.common.settings.Settings;import org.elasticsearch.common.transport.InetSocketTransportAddress;import org.elasticsearch.transport.client.PreBuiltTransportClient;public class TestEsClient {public static void main(String[] args) {try {//设置集群名称Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build();//创建clientTransportClient client = new PreBuiltTransportClient(settings);TransportAddress transportAddress = new TransportAddress(InetAddress.getByName("127.0.0.1"), Integer.valueOf(9300));client.addTransportAddress(transportAddress);//Get查询: 根据 (索引名称、类型、id)获取文档GetResponse response = client.prepareGet("INDEX", "TYPE", "id").execute().actionGet();//输出结果System.out.println(response.getSourceAsString());//关闭clientclient.close();} catch (Exception e) {e.printStackTrace();}}}
- 组合查询
转载至 https://blog.csdn.net/fanrenxiang/article/details/86509688
//复合查询-Bool查询public void boolDsl() {//Bool QueryBoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//电影名称必须包含我不是药神经过分词后的文本,比如我、不、是、药、神boolQueryBuilder.must(QueryBuilders.matchQuery(MovieSearch.NAME, "我不是药神"));//排除导演是张三的电影信息boolQueryBuilder.mustNot(QueryBuilders.termQuery(MovieSearch.DIRECTORS, "张三"));//别名中应该包含药神经过分词后的文本,比如药、神boolQueryBuilder.should(QueryBuilders.matchQuery(MovieSearch.ALIAS, "药神"));//评分必须大于9(因为es对filter会有智能缓存,推荐使用)boolQueryBuilder.filter(QueryBuilders.rangeQuery(MovieSearch.SCORE).gt(9));//name、actors、introduction、alias、label 多字段匹配"药神",或的关系boolQueryBuilder.filter(QueryBuilders.multiMatchQuery("药神", MovieSearch.NAME, MovieSearch.ACTORS, MovieSearch.INTRODUCTION, MovieSearch.ALIAS, MovieSearch.LABEL));String[] includes = {MovieSearch.NAME, MovieSearch.ALIAS, MovieSearch.SCORE, MovieSearch.ACTORS, MovieSearch.DIRECTORS, MovieSearch.INTRODUCTION};SearchRequestBuilder searchRequestBuilder = transportClient.prepareSearch(INDEX).setTypes(TYPE).setQuery(boolQueryBuilder).addSort(MovieSearch.SCORE, SortOrder.DESC).setFrom(0).setSize(10).setFetchSource(includes, null);SearchResponse searchResponse = searchRequestBuilder.get();if (!RestStatus.OK.equals(searchResponse.status())) {return;}for (SearchHit searchHit : searchResponse.getHits()) {String name = (String) searchHit.getSource().get(MovieSearch.NAME);//TODO}}
RestClient
https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.14/java-rest-high-search.html
- 通过http API 访问ES
- 没有语言限制。
ES提供了两个JAVA REST client 版本
- Java Low Level REST Client: 低级别的REST客户端,通过http与集群交互,用户需自己编组请求JSON串,及解析响应JSON串。兼容所有ES版本。
- Java High Level REST Client: 高级别的REST客户端,基于低级别的REST客户端,增加了编组请求JSON串、解析响应JSON串等相关api。使用的版本需要保持和ES服务端的版本一致,否则会有版本问题。
官方推荐使用高级版,低级版需要自己准确记住api。
import org.elasticsearch.client.RestClient;//初始化RestClient实例static RestClient restClient = RestClient.builder(new HttpHost("192.168.10.5", 9200, "http"),new HttpHost("192.168.10.6", 9200, "http"),new HttpHost("192.168.10.7", 9200, "http")).build()
//同步调用 Rest Api方法
public Response performRequest(String method, String endpoint, Header... headers) throws IOException
public Response performRequest(String method, String endpoint, Map<String, String> params, Header... headers) throws IOException
public Response performRequest(String method, String endpoint, Map<String, String> params,HttpEntity entity, Header... headers) throws IOException// (1) 执行一个基本的方法,验证es集群是否搭建成功Response response = restClient.performRequest("GET", "/", Collections.singletonMap("pretty", "true"));System.out.println(EntityUtils.toString(response.getEntity()));
//输出结果:
{"name" : "nd2","cluster_name" : "search","version" : {"number" : "2.3.4","build_hash" : "e455fd0c13dceca8dbbdbb1665d068ae55dabe3f","build_timestamp" : "2016-06-30T11:24:31Z","build_snapshot" : false,"lucene_version" : "5.5.0"},"tagline" : "You Know, for Search"
}// (2)验证es的某个索引是否存在
Response response = restClient.performRequest("HEAD","/product/pdt",Collections.<String, String>emptyMap());
System.out.println(response.getStatusLine().getReasonPhrase().equals("OK"));
//输出结果:
true// (3) 删除某个索引的指定条件的数据Map<String, String> paramMap = new HashMap<String, String>();paramMap.put("q", "id:"+id);paramMap.put("pretty", "true");
Response response = restClient.performRequest("DELETE","product/pdt/_query", paramMap);
System.out.println(EntityUtils.toString(response.getEntity()));
//输出结果:
{"took" : 0,"timed_out" : false,"_indices" : {"_all" : {"found" : 1,"deleted" : 0,"missing" : 0,"failed" : 0}},"failures" : [ ]
}// 用SearchSourceBuilder来构造 查询条件
String endPoint = '/index/_search?ignore_unavailable=true'SearchSourceBuilder requestSourceBuilder = new SearchSourceBuilder();
requestSourceBuilder.from(from);
requestSourceBuilder.size(size);HttpEntity entity = new NStringEntity(requestSourceBuilder.toString(), ContentType.APPLICATION_JSON);HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory consumerFactory = new HttpAsyncResponseConsumerFactory.HeapBufferedResponseConsumerFactory(BUFFER_SIZE);
Response response = restClient.performRequest("GET", endPoint,Collections.<String, String>emptyMap(),entity, consumerFactory);
ElasticSearch(ES)相关推荐
- [Elasticsearch] es 6.6 编译报错 SSL peer shut down incorrectly
1.概述 前提:[Elasticsearch] es 6.6 编译报错 java.net.ConnectException: Operation timed out Mac 编译es 6.8 报错 [ ...
- ElasticSearch (ES)学习之路(二)Win10安装ES,可视化界面,Kibanna
ElasticSearch (ES)学习之路(二)Win10安装ES,可视化界面,Kibanna 我前一段时间学习的时候ES 还是7.6.x 现在看ES 官网已经到了7.8.X了,迭代维护的速度还是挺 ...
- ElasticSearch es 插件开发
ElasticSearch es 插件开发 1. 插件分类 API Extension Plugins API扩展插件 通过添加新的API或功能向Elasticsearch添加新功能,通常与搜索或映射 ...
- Elasticsearch(ES)的下载与安装
Elasticsearch(ES)的下载与安装 1.安装 Java 在安装 Elasticsearch 之前,我们需要安装并配置好 JDK, 设置好环境变量 $JAVA_HOME. Elasticse ...
- ElasticSearch -- ES 7.x 集群版安装部署
向导 1. ElasticSearch 1.下载 2.配置 3.查看启动状态 4.注册宕机.开机自启 5.如果磁盘是SSD,建议修改IO调度算法 6.SSD磁盘,关闭numa绑核.hugepage 2 ...
- elasticsearch(es)分布式全文检索引擎 简介
0. 带着问题上路-ES是如何产生的? (1)思考:大规模数据如何检索? 如:当系统数据量上了10亿.100亿条的时候,我们在做系统架构的时候通常会从以下角度去考虑问题: 1)用什么数据库好?(MyS ...
- 使用canal同步MySQL数据到Elasticsearch(ES)
目录 1.功能及使用场景 1.1.功能介绍 1.2.使用场景 2.需求引入 3.canal文件下载及准备 3.1 下载文件 3.2 准备文件 4.deployer安装及效果测试 4.1.deploye ...
- [Elasticsearch] es 6.6 编译报错 java.net.ConnectException: Operation timed out
1.概述 Mac 编译es 6.8 报错 [lcc@lcc ~/IdeaProjects/source_code/elasticsearch]$ ./gradlew assemble Download ...
- Elasticsearch(ES) 基本知识
ES 学习笔记 Linux 安装ES及Kibana(7.17.4版本) ES基本使用 ES是一个基于Apache的开源索引库Lucene而构建的 开源.分布式.具有RESTful接口的全文搜索引擎, ...
最新文章
- 想学图像分割,强烈建议从这5篇图像分割算法综述
- matlib 7 在Win10上运行 runtime error
- Android -- 带你从源码角度领悟Dagger2入门到放弃(一)
- Hibernate type 与java 和 数据库类型对应
- 计算机专业自然辩证法期末论文,清华大学自然辩证法-期末论文.docx
- python求散点曲线下方面积
- 异常处理:try-catch-finally与throws的区别及使用情况
- 唯美动态个人404错误页面html源码
- Java和U3D比较,Unity热更方案 ILRuntime 和 toLua的比较
- 电脑wifi热点软件_手机WiFi信号太差怎么办?掌握这些方法,轻松解决这个问题...
- linux basename学习
- node重命名文件名_node文件批量重命名
- Tomcat CVE-2020-1938(CNVD-2020-10487) 漏洞复现
- Unity - Timeline 之 Timeline window(Timeline窗口)
- 深入理解 Laravel Eloquent(一)——基本概念及用法
- 第二届邯郸钢铁展洽会 | 图扑软件荣获“2022钢铁行业智造之星奖”
- Android 集成环信IM,实现头像和昵称的显示
- 如何用python画散点图矩阵_Python的散点图竟然能画这么好看
- 计算机上如何保存ico格式,怎么把图片转换成ico格式,又快又好
- vue3中使用webcamjs拍照