赞
踩
一:ElasticSearch安装
Elasticsearch 是使用 java 开发的,且 7.8 版本的 ES 需要 JDK 版本 1.8 以上,安装前注意java环境的准备。
官网地址:https://www.elastic.co/cn/
中文网址:https://elasticsearch.cn/download/
下载地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch
下载后解压即用,目录如下:
目录 | 含义 |
---|---|
bin | 可执行脚本目录 |
config | 配置目录 |
data | 数据文件 (刚解压的时候没有,启动后自动生成) |
jdk | 内置 JDK 目录 |
lib | 类库 |
logs | 日志目录 |
modules | 模块目录 |
plugins | 插件目录 |
进入bin目录下,点击elasticsearch.bat文件启动:
启动成功后:(初始访问地址:localhost:9200)
初始默认:9300 端口为 Elasticsearch 集群间组件的通信端口,9200 端口为浏览器访问的 http
协议 RESTful 端口。
自己设置方法如下:
进入config文件夹,打开elasticsearch.yml配置文件进行编辑
配置如下内容到elasticsearch.yml:
node.name: node-1001 #节点名称,要是在集群内,则要唯一
network.host: localhost #设置ip地址
http.port: 1001 #设置http端口
transport.tcp.port: 9301 #设置TCP通信监听端口
二:操作工具
可以使用kibana或者postman
Postman 官网:https://www.getpostman.com
Postman 下载:https://www.getpostman.com/apps
kibana百度网盘下载:https://pan.baidu.com/s/1hILVKNJkxF2yDxVmcyTn9w
提取码:u5pq,或者去开头的中文网去下载也可以。
这里使用postman介绍ElasticSearch操作:
数据库是增删改查CRUD,索引也有相应的操作,ElasticSearch是为搜索而生的,主要还是搜索。
对比关系型数据库,创建索引就等同于创建数据库
在 Postman 中,向 ES 服务器发 PUT 请求创建索引shopping :http://127.0.0.1:9200/shopping
这里可以把索引类比数据库,创建索引就等同于创建数据库
使用get获取shopping索引信息:
查看所有索引:
索引及其内文档的属性和含义:
表头 | 含义 |
---|---|
health | 当前服务器健康状态:green(集群完整) yellow(单点正常、集群不完整) red(单点不正常) |
status | 索引打开、关闭状态 |
index | 索引名 |
uuid | 索引统一编号 |
pri | 主分片数量 |
rep | 副本数量 |
docs.count | 可用文档数量 |
docs.deleted | 文档删除状态(逻辑删除) |
store.size | 主分片和副分片整体占空间大小 |
pri.store.size | 主分片占空间大小 |
删除索引,选择delete即可,这里是直接删除索引,而上表属性中的docs.deleted是索引中的文档的逻辑删除的标记字段
删了后在get,报404,索引删除为物理删除
下面是对索引内文档操作:/_doc,再添加JSON类型请求内容即可。
使用post添加一个user:
上面的数据创建后,由于没有指定数据唯一性标识(ID),默认情况下,ES 服务器会随机生成一个,即上图的"_id"字段,每次创建新的内容,就会随机生成一个不同的。
如果想要自定义唯一性标识,需要在创建时指定:http://127.0.0.1:1001/user/_doc/1
查看文档时,需要指明文档的唯一性标识,类似于 MySQL 中数据的主键查询
在 Postman 中,向 ES 服务器发 GET 请求 :http://127.0.0.1:9200/shopping/_doc/1
更新一条内容的局部信息:比如更改id为1数据的名字 “前女友” 为 “前前女友”
每次更新数据后,这条数据的版本+1,这里用了乐观锁,比如后面再想更新version=1的话就会失败
删除id为1的“前前女友”的user信息:此为逻辑删除,如下:
使用kibana创建映射:/user/_mapping
此处我先把user删了后,重新创建了
三:查询操作合集:
此处我设置的索引user,可以索引的字段仅为name:
查询代码:(可直接复制到kibana
中使用)
1.查询所有文档:
GET /user/_search
{
"query": {
"match_all": {}
}
}
2.匹配查询:
match
匹配类型查询,会把查询条件进行分词,然后进行查询,多个词条之间是or
的关系
GET /user/_search
{
"query": {
"match": {
"name":"王语嫣"
}
}
}
3.字段匹配查询:
multi_match
与match
类似,不同的是它可以在多个字段中查询。
GET /user/_search
{
"query": {
"multi_match": {
"query": "王语嫣",
"fields": ["name","id"]
}
}
}
4.关键字精准查询:
这个
term
查询不对查询条件进行分词,
要是text
文本类型就会出错,keyword
可以进行此类查询
向
user
中再加一个keyword
类型的id
字段
PUT /user/_mapping
{
"properties": {
"id":{
"type": "keyword",
"index": true
}
}
}
添加一条数据
PUT /user/_doc/1004
{
"name": "王嫣",
"sex": "女",
"age": 18,
"id": 1004
}
进行关键字精准查询:
GET /user/_search
{
"query": {
"term": {
"id": {
"value": "1004"
}
}
}
}
5.多关键字查询:
terms
查询和term
查询一样,但它允许你指定多值进行匹配。
如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件,类似于 mysql 的 in
当然,一定要记得查询的字段为关键字keyword
类型,不然查不到内容
GET /user/_search
{
"query": {
"terms": {
"id": ["1004","王子嫣"]
}
}
}
6.组合查询:
bool
把各种其它查询通过must
(必须 )、must_not
(必须不)、should
(应该)的方式进行组合
GET /user/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "王"
}
}
],
"must_not": [
{
"match": {
"age": "100"
}
}
],
"should": [
{
"match": {
"id": "1004"
}
}
]
}
}
}
7.范围查询:
操作符 | 说明 |
---|---|
gt | 大于> |
gte | 大于等于>= |
lt | 小于< |
lte | 小于等于<= |
例如:查询年龄在30~35闭区间
{
"query": {
"range": {
"age": {
"gte": 30,
"lte": 35
} } } }
8.高亮查询:
GET /user/_search
{
"query": {
"match": {
"name": "王语嫣"
}
},
"highlight": {
"pre_tags": "<font color='red'>",
"post_tags": "</font>",
"fields": {
"name": {}
}
}
}
9.分页查询+排序:
也可设置多字段排序,主次为代码顺序
GET /user/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"age": {
"order": "desc"
}
}
],
"from": 0,
"size": 2
}
10.查询需要的字段(例如只要名字+年龄)
GET /user/_search
{
"_source": ["name","age"],
"query": {
"terms": {
"id": [
"1004",
"1002"
]
}
}
}
11.过滤查询:
includes:来指定想要显示的字段
excludes:来指定不想要显示的字段
GET /user/_search
{
"_source": {
"includes": ["name","age"],
"excludes": ["name"]
},
"query": {
"term": {
"id": {
"value": "1004"
}
}
}
}
12.聚合查询:
聚合允许使用者对 es 文档进行统计分析,类似与关系型数据库中的 group by,当然还有很
多其他的聚合,例如取最大值、平均值等等。
最大值(最小值改成min即可):
平均值:
查询还有很多,此处不再列举
四:集成到spring:
版本的对应:
需要导入的依赖包:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
application.properties配置文件:
# es服务地址
elasticsearch.host=127.0.0.1
# es服务端口
elasticsearch.port=1001
# 配置日志级别,开启debug日志
logging.level.com.atguigu.es=debug
ElasticSearchConfig.java:
///读取配置文件中的ES内容
@ConfigurationProperties(prefix = "elasticsearch")
@Configuration
@Data
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {
private String host ;
private Integer port ;
@Override
public RestHighLevelClient elasticsearchClient() {
RestClientBuilder builder = RestClient.builder(new HttpHost(host, port));
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(builder);
return restHighLevelClient;
}
}
测试类文件:
///测试查看user索引信息
@Test
@Rollback(value = false)
public void createIndex() throws Exception {
RestHighLevelClient client = new ElasticsearchConfig().elasticsearchClient();
GetIndexRequest getIndexRequest =new GetIndexRequest("user");
GetIndexResponse getIndexResponse = client.indices().get(getIndexRequest, RequestOptions.DEFAULT);
System.out.println(getIndexResponse.getAliases());
System.out.println(getIndexResponse.getMappings());
System.out.println(getIndexResponse.getSettings());
client.close();
}
五:创建ElasticSearch集群:
配置服务器集群时,集群中节点数量没有限制,大于等于 2 个节点就可以看做是集群了。一般出于高性能及高可用方面来考虑集群中节点数量都是 3 个以上。
集群 Cluster:
一个集群就是由一个或多个服务器节点组织在一起,共同持有整个的数据,并一起提供索引和搜索功能。一个 Elasticsearch 集群有一个唯一的名字标识,这个名字默认就是”elasticsearch”。这个名字是重要的,因为一个节点只能通过指定某个集群的名字,来加入这个集群。
节点 Node:
集群中包含很多服务器,一个节点就是其中的一个服务器。作为集群的一部分,它存储数据,参与集群的索引和搜索功能。一个节点也是由一个名字来标识的,默认情况下,这个名字是一个随机的漫威漫画角色的名字,这个名字会在启动的时候赋予节点。这个名字可以确定网络中的哪些服务器对应于 Elasticsearch 集群中的哪些节点。一个节点可以通过配置集群名称的方式来加入一个指定的集群。默认情况下,每个节点都会被安排加入到一个叫做“elasticsearch”的集群中,这意味着,如果你在你的网络中启动了若干个节点,并假定它们能够相互发现彼此,它们将会自动地形成并加入到一个叫做“elasticsearch”的集群中。如果当前你的网络中没有运行任何 Elasticsearch 节点,这时启动一个节点,会默认创建并加入一个叫做“elasticsearch”的集群。
部署集群:
直接将node1001文件复制两份即可,然后分别命名各自的节点名称:
然后删除各个节点的data文件夹,然后日志文件夹里的内容也可以全部删除:
然后更改这三个节点的config文件:
elasticsearch.yml
文件更改:
#集群名称,节点之间要保持一致
cluster.name: my-elasticsearch
#节点名称,集群内要唯一
node.name: node-1001
#node.name: node-1002
#node.name: node-1003
node.master: true
node.data: true
#ip 地址
network.host: localhost
#http 端口
http.port: 1001
#http.port: 1002
#http.port: 1003
#tcp 监听端口
transport.tcp.port: 9301
#transport.tcp.port: 9302
#transport.tcp.port: 9303
#候选主节点的地址,在开启服务后可以被选为主节点
discovery.seed_hosts: ["localhost:9302", "localhost:9303"]
#discovery.seed_hosts: [“localhost:9301”, “localhost:9303”]
#discovery.seed_hosts: [“localhost:9301”, “localhost:9302”]
discovery.zen.fd.ping_timeout: 1m
discovery.zen.fd.ping_retries: 5
#集群内的可以被选为主节点的节点列表
cluster.initial_master_nodes: ["node-1001", "node-1002","node-1003"]
#跨域配置
#action.destructive_requires_name: true
http.cors.enabled: true
http.cors.allow-origin: "*"
最后,直接挨个启动即可:
启动后可以看到集群的健康值: green
还可以看到每个索引都有主分片,每个主分片有一个副本。
当然,这个可以自己设置:
比如创建product索引(三个主分片,每个主分片有一个备份):
PUT /product
{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 1
}
}
创建好后,查看集群就会是:
这里的重边框为主分片,其余为对应主分片的副本:
补充:
1.水平扩容:
就是新增节点。
2.垂直扩容:
就是增加主分片的副本数量(副本不跟主分片在同一个节点上),副本数量的增加,集群搜索性能可以成倍提升。
要是在同节点上增加主节点自己的副本数量,只会造成数据的冗余,降低性能
3集群状态:
如果现在节点数目不足以分配主分片指定数目的所有副本,集群状态就会变成yellow
4.路由计算:
当索引一个文档的时候,文档会被存储到一个主分片中。 Elasticsearch 如何知道一个文档应该存放到哪个分片中呢?当我们创建文档时,它如何决定这个文档应当被存储在分片1 还是分片 2 中呢?首先这肯定不会是随机的,否则将来要获取文档的时候我们就不知道从何处寻找了。这个过程是根据下面这个公式决定的:
shard=hash(routing)%number_of_primary_shards
routing 是一个可变值,默认是文档的 _id ,也可以设置成一个自定义的值。 routing 通过hash 函数生成一个数字,然后这个数字再除以number_of_primary_shards (主分片的数量)后得到余数 。这个分布在 0 到number_of_primary_shards-1 之间的余数,就是我们所寻求的文档所在分片的位置。
所以说,索引创建的时候,主分片的数量就确定好了
5.倒排索引:
想一下,互联网体系收录的庞大的搜索引擎中的文档数目肯定是个夸张可以到超级大的数字,要是用K_V对来查询,那直接龟速…
于是乎产生了倒排索引。
即K_V的反向:
把文件ID对应到关键词的映射转换为关键词到文件ID的映射,每个关键词都对应着一系列的文件,这些文件中都出现这个关键词。
比如
:要查询包含“java”和“springboot”两个词,然后如果查到java在doc1中,也在doc2中,springboot只在doc1中;那么可以得出:
doc1和doc2两个文档都匹配,但是第一个文档比第二个匹配度更高。如果我们使用仅计算匹配词条数量的简单相似性算法,那么我们可以说,对于我们查询的相关性来讲,第一个文档比第二个文档更佳。
六:分词器:
ElasticSearch有自己的分词器,用户也可以自己定义一个分词器文档:
下载地址:https://pan.baidu.com/s/1qqAQjFXtIywtalxBf17rOw
提取码:7evw
然后在config文件中创建一个dic词典文件,自己取个名字:
然后直接在这个文件中写入自定义的词语:
保存后,打开IKAnalyzer.cfg.xml,将我们的分词器配置上
保存后,重启节点,启动后,测试如下:
OK,今日总结至此,之后续写springboot集成ElasticSearch。
各位看官有发现写的不当之处,请评论多多指出,感谢
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。