【elasticsearch从入门到实战】完整合集版,带思维导图

简介

elasticsearch

全文搜索属于最常见的需求,开源的 Elasticsearch 是目前全文搜索引擎的首选。它可以快速地存储、搜索和分析海量数据。
维基百科、Stack Overflow、Github 都采用它。
Elastic 的底层是开源库 Lucene。
但是,你没法直接用 Lucene,必须自己写代码去调用它的接口。
Elastic 是 Lucene 的封装,提供了 REST API 的操作接口,开箱即用。
REST API:天然的跨平台。

一、基本概念

1、Index(索引)

动词,相当于 MySQL 中的 insert;
名词,相当于 MySQL 中的 Database

2、Type(类型)

在 Index(索引)中,可以定义一个或多个类型;
类似于 MySQL 中的 Table;每一种类型的数据放在一起。

3、Document(文档)

保存在某个索引(Index)下,某种类型(Type)的一个数据(Document),文档是 JSON 格式的,
Document 就像是 MySQL 中的某个 Table 里面的内容。

4、倒排索引机制

记录
红海 1,2,3,4,5
行动 1,2,3
探索 2,5
特别 3,5
记录篇 4
特工 5

分词:将整句分拆为单词

保存的记录

  • 1-红海行动
  • 2-探索红海行动
  • 3-红海特别行动
  • 4-红海记录篇
  • 5-特工红海特别探索

检索
1)、红海特工行动?
2)、红海行动?

相关性得分


二、Docker 安装

1、下载镜像文件

下载elasticsearch

docker pull elasticsearch:7.4.2 # 存储和检索数据

下载kibana

docker pull kibana:7.4.2 # 可视化检索数据

 

注意:elasticsearch 要和 kibana 的版本保持一致!

2、创建实例

1. ElasticSearch

mkdir -p /mydata/elasticsearch/config # 在mydata文件夹下创建es的config文件夹,将docker中es的配置挂载在外部,当我们在linux虚拟机中修改es的配置文件时,就会同时修改docker中的es的配置
mkdir -p /mydata/elasticsearch/data #在mydata文件夹下创建es的data文件夹
echo "http.host:0.0.0.0" >> /mydata/elasticsearch/config/elasticsearch.yml # [http.host:0.0.0.0]允许任何远程机器访问es,并将其写入es的配置文件中

chmod -R 777 /mydata/elasticsearch/ # 保证权限问题

docker run --name elasticsearch -p 9200:9200 -p 9300:9300 \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms64m -Xmx128m" \
-v /mydata/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /mydata/elasticsearch/data:/usr/share/elasticsearch/data \
-v /mydata/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-d elasticsearch:7.4.2

# docker run --name elasticsearch 创建一个es容器并起一个名字;
# -p 9200:9200 将linux的9200端口映射到docker容器的9200端口,用来给es发送http请求
# -p 9300:9300 9300是es在分布式集群状态下节点之间的通信端口  \ 换行符
# -e 指定一个参数,当前es以单节点模式运行
# *注意,ES_JAVA_OPTS非常重要,指定开发时es运行时的最小和最大内存占用为64M和128M,否则就会占用全部可用内存
# -v 挂载命令,将虚拟机中的路径和docker中的路径进行关联
# -d 后台启动服务

安装完 elasticsearch 后我们来启动一下,会发现使用docker ps命令查看启动的容器时没有找到我们的 es,这是因为目前 es 的配置文件的权限导致的,因此我们还需要修改一下 es 的配置文件的权限:

[root@10 config]# cd ../
[root@10 elasticsearch]# ls
config  data  plugins
[root@10 elasticsearch]# cll
bash: cll: command not found
[root@10 elasticsearch]# ll
total 0
drwxr-xr-x. 2 root root 31 May 21 14:55 config
drwxr-xr-x. 2 root root  6 May 21 14:52 data
drwxr-xr-x. 2 root root  6 May 21 15:14 plugins
[root@10 elasticsearch]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
53c0e82ded18        redis               "docker-entrypoint.s…"   6 weeks ago         Up 4 hours          0.0.0.0:6379->6379/tcp              redis
e1c1b5a6012e        mysql:5.7           "docker-entrypoint.s…"   6 weeks ago         Up 4 hours          0.0.0.0:3306->3306/tcp, 33060/tcp   mysql
[root@10 elasticsearch]# chmod -R 777 /mydata/elasticsearch/
[root@10 elasticsearch]# ll
total 0
drwxrwxrwx. 2 root root 31 May 21 14:55 config
drwxrwxrwx. 2 root root  6 May 21 14:52 data
drwxrwxrwx. 2 root root  6 May 21 15:14 plugins

修改完文件权限后,我们使用docker start elasticsearch再次启动 es,使用docker ps命令查看后发现容器还是没有启动,这是问什么呢?
我们使用docker logs elasticsearch看一下 es 的启动日志:

[root@10 elasticsearch]# docker logs elasticsearch
OpenJDK 64-Bit Server VM warning: Option UseConcMarkSweepGC was deprecated in version 9.0 and will likely be removed in a future release.
2020-05-21 15:14:13,179 main ERROR No Log4j 2 configuration file found. Using default configuration (logging only errors to the console), or user programmatically provided configurations. Set system property 'log4j2.debug' to show Log4j 2 internal initialization logging. See https://logging.apache.org/log4j/2.x/manual/configuration.html for instructions on how to configure Log4j 2
Exception in thread "main" SettingsException[Failed to load settings from [elasticsearch.yml]]; nested: ParsingException[Failed to parse object: expecting token of type [START_OBJECT] but found [VALUE_STRING]];
        at org.elasticsearch.common.settings.Settings$Builder.loadFromStream(Settings.java:1097)
        at org.elasticsearch.common.settings.Settings$Builder.loadFromPath(Settings.java:1070)
        at org.elasticsearch.node.InternalSettingsPreparer.prepareEnvironment(InternalSettingsPreparer.java:83)
        at org.elasticsearch.cli.EnvironmentAwareCommand.createEnv(EnvironmentAwareCommand.java:95)
        at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86)
        at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:125)
        at org.elasticsearch.cli.Command.main(Command.java:90)
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:115)
        at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92)
Caused by: ParsingException[Failed to parse object: expecting token of type [START_OBJECT] but found [VALUE_STRING]]
        at org.elasticsearch.common.xcontent.XContentParserUtils.ensureExpectedToken(XContentParserUtils.java:78)
        at org.elasticsearch.common.settings.Settings.fromXContent(Settings.java:617)
        at org.elasticsearch.common.settings.Settings.access$400(Settings.java:82)

 上述错误是由于我之前配置elasticsearch.yml文件的时候k-v键值对配置错误导致的,查看 yml 文件会发现我配置的内容是这样的:

http.host:0.0.0.0

修改并保存之后再次使用docker start elasticsearch启动 es,使用docker ps命令产看后可以看到我的 es 容器已经启动起来了: 

在浏览器地址栏访问http://192.168.56.10:9200/,可以看到 es 启动成功后返回类似下面的数据:

注意192.168.56.10是我的linux虚拟机的地址,读者需要根据自己的虚拟机地址来进行访问

2, Kibana

安装可视化界面

docker run --name kibana -e ELASTICSEARCH_HOSTS=http://192.168.56.10:9200 -p 5601:5601 \
-d kibana:7.4.2

注意,一定要将192.168.56.10修改为自己的虚拟机地址 

安装完成后在浏览器地址栏访问http://192.168.56.10:5601/,可以看到 kibana 已经启动成功:

  选择yes或no都可以:

使用我们自己的数据:

  

安装成功的界面: 

注意:如果访问http://192.168.56.10:5601/时出现下面的提示,可以稍等一会,可能是 kibana 还没有启动成功

也可以使用docker logs kibana来查看一下 kibana 的启动日志,下面的日志表示 kibana 启动正常:

三、初步检索

对 ES 的所有请求都被封装成了 REST API,因此我们可以使用 postman 来访问它。

使用 postman 或者在浏览器地址栏输入请求路径http://192.168.56.10:9200/_cat/xxx

1、_cat

  • GET /_cat/nodes:查看所有节点

  • GET /_cat/health:查看es健康状况

  • GET /_cat/master:查看主节点

  • GET /_cat/indices:查看所有索引 ;相当于 MySQL 的 show databases;

 

 

2、索引一个文档(对应成Mysql就是保存一条记录)

保存一个数据,保存在哪个索引的哪个类型下,指定用哪个唯一标识PUT customer/external/1
在 customer 索引下的 external 类型下保存 1 号数据为

PUT customer/external/1
{
"name":"lohn Doe"
}
PUTPOST 都可以;
POST 新增。如果不指定id,会自动生成 id。指定 id 就会修改这个数据,并新增版本号;
PUT 可以新增也可以修改。PUT 必须指定 id;由于 PUT 需要指定 id,我们一般都用来做修改;

在 postman 地址栏中输入 http://192.168.56.10:9200/customer/external/1,使用 put 方法,输入参数体:

{
"name":"lohn Doe"
}

可以看到创建记录成功:

再一次发送请求后得到如下结果:

{
    "_index": "customer",
    "_type": "external",
    "_id": "1",
    "_version": 2, //注意版本号
    "result": "updated",//注意结果是 update
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 1, //注意序列号
    "_primary_term": 1
}

 所以 put 方法既可以用来新增,也可以用来更新。

在 postman 中使用 post 方法发送 http://192.168.56.10:9200/customer/external/ 请求,注意没有带 id,使用的还是上面 put 方法中的参数,
可以看到创建记录成功,es 帮我们生成了一个id:

当我们使用这个 id 再一次发送 post 请求时,就会变成更新操作:

所以 post 方法不带 id 时是新增,带 id 不存在时也是新增,带 id 且数据存在时是更新操作。

那么问题来了,put 和 post 方法有啥区别呢?如果使用 put 方法不带 id 发送请求行不行?

可以看到使用 put 方法不带 id 请求会报错,也就是说 put 是不允许不带 id 请求的,而 post 是允许的。

3、查询文档

3.1、get查询数据

GET customer/external/1
结果:
{
"_index": "customer", //在哪个索引
"_type": "external", //在哪个类型
"_id": "1", //记录id
"_version": 4, //版本号
"_seq_no": 5, //并发控制字段,每次更新就会+1,用来做乐观锁
"_primary_term": 1, //同上,主分片重新分配,如重启,就会变化
"found": true, //表示找到了数据
"_source": { //数据内容
"name": "lohn Doe"
}
}
更新携带 ?if_seq_no=0&if_primary_term=1

在 postman 中使用 get 方法请求 http://192.168.56.10:9200/customer/external/1,会得到如下的结果:

{
    "_index": "customer",   //在哪个索引
    "_type": "external",    //在哪个类型
    "_id": "1",             //记录id
    "_version": 4,          //版本号
    "_seq_no": 5,           //并发控制字段,每次更新就会+1,用来做乐观锁
    "_primary_term": 1,     //同上,主分片重新分配,如重启,就会变化
    "found": true,          //表示找到了数据
    "_source": {            //数据内容
        "name": "lohn Doe"
    }
}

 

3.2、乐观锁修改

要使用乐观锁修改,我们就需要在 put 或 post 请求的路径中加上?if_seq_no=0&if_primary_term=1字段;
我们在 postman 中使用 put 方法发送 http://192.168.56.10:9200/customer/external/1?if_seq_no=0&if_primary_term=1 请求,参数传

{
"name":"update"
}

执行更新错操作后,出现如下返回结果:

如果我们使用最新的序列号去更新,就会返回状态为 200 的更新成功的结果:

4、更新文档

更新操作 参数或结论
POST
customer/external/1/_update
{
"doc": {
"name": "Jane Doe",
"age": 20
}
}
或者POST
customer/external/1
{
"name": "John Nash2"
}
或者PUT
customer/external/1
{
"name": "John Nash3"
}
不同 POST 操作会对比源文档数据,如果相同不会有什么操作,文档 version 、_seq_no 不增加;
PUT 操作总会将数据重新保存并增加 version 版本;
带 _update 对比元数据如果一样就不进行任何操作。
看场景 对于大并发更新,不带update;
对于大并发查询偶尔更新,带update;对比更新,重新计算分配规则。
更新同时增加属性
POST
customer/external/1/_update
{
"doc": {
"name": "Jane Doe",
"age": 20
}
}
更新同时增加属性
PUT&POST
customer/external/1
{
"name": "John Nash2",
"age": 40
}

使用带 _update 的 post 请求更新数据,在 postman 中使用 post 方法发送 http://192.168.56.10:9200/customer/external/1/_update 请求,参数传:

{
     "doc": {
          "name": "John Nash"
     }
}

发送请求可以得到下面的结果,可以看到更新成功:

再次发送请求,可以看到如果数据相同,对比原来数据,与原来一样就什么都不做,_version_seq_no也不会变:

使用_update 的 post 请求更新数据,在 p

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值