ElasticSearch

ElasticSearch

一: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_matchmatch类似,不同的是它可以在多个字段中查询。

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。

各位看官有发现写的不当之处,请评论多多指出,感谢

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值