前言
近期想尝试使用 Elasticsearch + analysis-ik 组合来实现全文搜索,所以需要在自己的Linux服务器上安装Java1.8的环境。
安装Java1.8
使用 yum search 命令搜索 Java 对应的包
yum search java
从结果中,我们找到我们需要的包名:java-1.8.0-openjdk.x86_64
<img src="https://pic1.zhimg.com/v2-1869785b7883d587a3323f2dd46a6d08_b.jpg" data-caption="" data-size="normal" data-rawwidth="578" data-rawheight="633" class="origin_image zh-lightbox-thumb" width="578" data-original="https://pic1.zhimg.com/v2-1869785b7883d587a3323f2dd46a6d08_r.jpg">
接下来,我们就可以使用yum安装了:
yum install java-1.8.0-openjdk.x86_64
<img src="https://pic4.zhimg.com/v2-be6c28add811546397d5173d24fcdd13_b.jpg" data-caption="" data-size="normal" data-rawwidth="397" data-rawheight="214" class="content_image" width="397">
到了这里,就证明我们已经安装完成了,接下来我们执行以下 java -version 命令,查看是否安装成功:
java -version
<img src="https://pic1.zhimg.com/v2-b81dc508b03b5475d85bdb3a049b268c_b.jpg" data-caption="" data-size="normal" data-rawwidth="412" data-rawheight="67" class="content_image" width="412">
这就证明我们的 java1.8 已经安装成功了。
安装Elasticsearch
去 Elasticsearch官网 获取最新的下载地址,使用wget命令下载
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.3.1.tar.gz
<img src="https://pic3.zhimg.com/v2-626380ba380c7bf0bb97ee17501a0d72_b.jpg" data-caption="" data-size="normal" data-rawwidth="795" data-rawheight="205" class="origin_image zh-lightbox-thumb" width="795" data-original="https://pic3.zhimg.com/v2-626380ba380c7bf0bb97ee17501a0d72_r.jpg">
我们已经下载好了Elasticsearch,接下来我们需要对其进行解压和启动:
# 解压
tar -xzvf elasticsearch-6.3.1.tar.gz
# 进入elasticsearch-6.3.1文件夹
cd elasticsearch-6.3.1
# 进入bin文件夹
cd bin/
# 启动
./elasticsearch
这时小编发现,无论怎么启动都启动不成功,后来百度了一下,说是新版本不允许root启动,软件目录没有相应权限,解决方法如下:
# 新建用户组
groupadd elasticsearchs
# 新建用户
useradd -g elasticsearchs es
# 设置密码
passwd es
# 切换用户
su es
# 重新启动
./elasticsearch
小编这里又出现了以下错误(Exception in thread "main" java.nio.file. AccessDeniedException):
<img src="https://pic3.zhimg.com/v2-2f05e1ef66703e890f3016885cb2888e_b.jpg" data-caption="" data-size="normal" data-rawwidth="577" data-rawheight="224" class="origin_image zh-lightbox-thumb" width="577" data-original="https://pic3.zhimg.com/v2-2f05e1ef66703e890f3016885cb2888e_r.jpg">
这个错误是由于该用户的文件权限不足,而拒绝被执行,修改如下:
su root
回到elasticsearch-6.3.1(小编的是这个目录)所在目录:
<img src="https://pic4.zhimg.com/v2-64f0f3fbf5067791cd66c6c0abb467b3_b.jpg" data-caption="" data-size="normal" data-rawwidth="591" data-rawheight="165" class="origin_image zh-lightbox-thumb" width="591" data-original="https://pic4.zhimg.com/v2-64f0f3fbf5067791cd66c6c0abb467b3_r.jpg">
我们可以看到这个文件夹的用户组权限还是属于root,所以我们需要更改这个用户组:
# 执行chowm
# es - 用户名
# elasticsearchs - 用户组
# elasticsearch-6.3.1 elasticsearch 文件夹
chown -R es:elasticsearchs elasticsearch-6.3.1/
我们重新看看权限:
<img src="https://pic4.zhimg.com/v2-eec63b388eaa30af27b76d577c225ae7_b.jpg" data-caption="" data-size="normal" data-rawwidth="596" data-rawheight="164" class="origin_image zh-lightbox-thumb" width="596" data-original="https://pic4.zhimg.com/v2-eec63b388eaa30af27b76d577c225ae7_r.jpg">
现在,我们就能看到我们的 Elasticsearch 文件夹的权限是属于我们的 elasticsearchs 用户组下的 es 用户了。我们再来启动:
# 进入bin目录
cd elasticsearch-6.3.1/bin/
# 启动 -d 表示在后台启动服务,否则窗口一关闭,服务就停止
./elasticsearch -d
接下来我们来看看效果:
<img src="https://pic3.zhimg.com/v2-23f880739d0a5fea3544fdde8de5222e_b.jpg" data-caption="" data-size="normal" data-rawwidth="1900" data-rawheight="767" class="origin_image zh-lightbox-thumb" width="1900" data-original="https://pic3.zhimg.com/v2-23f880739d0a5fea3544fdde8de5222e_r.jpg">
这里就证明我们启动成功了,接下来我们使用 curl localhost:9200 命令检测是否真正的成功:
curl localhost:9200
我们来看看效果图:
<img src="https://pic4.zhimg.com/v2-12a36876edadaa4bd74dd504eb5499fb_b.jpg" data-caption="" data-size="normal" data-rawwidth="381" data-rawheight="243" class="content_image" width="381">
我们在使用 ps -ef | grep ela 来查看一下是否启动了该服务
ps -ef | grep ela
<img src="https://pic2.zhimg.com/v2-eabaae25e273fa524f26fb782ec21cc1_b.jpg" data-caption="" data-size="normal" data-rawwidth="750" data-rawheight="89" class="origin_image zh-lightbox-thumb" width="750" data-original="https://pic2.zhimg.com/v2-eabaae25e273fa524f26fb782ec21cc1_r.jpg">
看到这一步,我们的就已经成功的启动了 Elasticsearch 服务了。
Elasticsearch 新建和删除 Index
新建 Index,可以直接向 Elastic 服务器发出 PUT 请求。下面的例子是新建一个名叫 kafei 的 Index。
curl -X PUT 'localhost:9200/kafei'
我们可以看到下面的效果:
<img src="https://pic1.zhimg.com/v2-3093140bd427255f705befc45d60d7ac_b.jpg" data-caption="" data-size="normal" data-rawwidth="636" data-rawheight="35" class="origin_image zh-lightbox-thumb" width="636" data-original="https://pic1.zhimg.com/v2-3093140bd427255f705befc45d60d7ac_r.jpg">
acknowledged 为 true 的时候,代表操作成功。
{
"acknowledged":true,
"shards_acknowledged":true
}
我们来查看一下当前的索引信息:
curl -X GET 'http://localhost:9200/_cat/indices?v'
<img src="https://pic2.zhimg.com/v2-6fae867c999f176dc1398b4f4b36efe9_b.jpg" data-caption="" data-size="normal" data-rawwidth="727" data-rawheight="53" class="origin_image zh-lightbox-thumb" width="727" data-original="https://pic2.zhimg.com/v2-6fae867c999f176dc1398b4f4b36efe9_r.jpg">
我们已经能看到我们刚刚创建的索引了,接下来我们使用 DELECT 请求,来删除我们的索引:
curl -X DELETE 'localhost:9200/kafei'
<img src="https://pic3.zhimg.com/v2-93a60379c45fe27b3ed909179e88e85e_b.jpg" data-caption="" data-size="normal" data-rawwidth="449" data-rawheight="35" class="origin_image zh-lightbox-thumb" width="449" data-original="https://pic3.zhimg.com/v2-93a60379c45fe27b3ed909179e88e85e_r.jpg">
执行之后,我们可以看到一组json值,同理,acknowledged 为 true 的时候,代表操作成功。
{
"acknowledged":true
}
我们再来看看我们创建的索引:
<img src="https://pic1.zhimg.com/v2-42cfa753cf42bbc78e9c01dd2f678c54_b.jpg" data-caption="" data-size="normal" data-rawwidth="606" data-rawheight="48" class="origin_image zh-lightbox-thumb" width="606" data-original="https://pic1.zhimg.com/v2-42cfa753cf42bbc78e9c01dd2f678c54_r.jpg">
现在,我们已经没有索引了。
Analysis-ik 中文分词设置
首先我们需要进入我们的 elasticsearch 根目录下:
# 这是小编的 elasticsearch 的根目录
cd /home/elasticsearch-6.3.1/
去 elasticsearch-analysis-ik 的 git 中去找到符合你当前 Elasticsearch 版本的插件包,然后使用 ./bin/elasticsearch-plugin 进行安装:
./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.3.1/elasticsearch-analysis-ik-6.3.1.zip
<img src="https://pic2.zhimg.com/v2-1fdfd2ecb25fd2d50896b160a6187c19_b.jpg" data-caption="" data-size="normal" data-rawwidth="753" data-rawheight="189" class="origin_image zh-lightbox-thumb" width="753" data-original="https://pic2.zhimg.com/v2-1fdfd2ecb25fd2d50896b160a6187c19_r.jpg">
这样,我们就安装好了,我们重启我们的 elasticsearch 服务。
<img src="https://pic3.zhimg.com/v2-c0fb804c0559bde17b5a56156ec47926_b.jpg" data-caption="" data-size="normal" data-rawwidth="653" data-rawheight="160" class="origin_image zh-lightbox-thumb" width="653" data-original="https://pic3.zhimg.com/v2-c0fb804c0559bde17b5a56156ec47926_r.jpg">
这里边小编我们启动不了,我们看到出现的错误是:OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000e5330000, 449642496, 0) failed; error='Cannot allocate memory' (errno=12):
<img src="https://pic3.zhimg.com/v2-3a7a505460ac79ef2700dad1ee1bfcce_b.jpg" data-caption="" data-size="normal" data-rawwidth="1399" data-rawheight="112" class="origin_image zh-lightbox-thumb" width="1399" data-original="https://pic3.zhimg.com/v2-3a7a505460ac79ef2700dad1ee1bfcce_r.jpg">
这里边提示我们说内存不足,导致分配内存失败,所以我们需要去修改下我们分配的内存大小:
# 进入根目录下的config文件夹
cd config/
# 编辑jvm.options文件
vim jvm.options
# 找到内存设置,并设置成合适的内存,由于小编的是1G内存的服务器,所以只设置了400M的内存
-Xms400m
-Xmx400m
设置完成之后,保存退出,重启服务,就可以看到启动成功了:
<img src="https://pic3.zhimg.com/v2-31aea886b4ad20e2401285f3510ba662_b.jpg" data-caption="" data-size="normal" data-rawwidth="637" data-rawheight="69" class="origin_image zh-lightbox-thumb" width="637" data-original="https://pic3.zhimg.com/v2-31aea886b4ad20e2401285f3510ba662_r.jpg">
设置索引
现在我们新建一个 Index,指定需要分词的字段,凡是需要搜索的中文字段都需要单独设置一下:
curl -X PUT 'localhost:9200/kafei' -H 'Content-Type: application/json' -d '
{
"mappings": {
"article": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"desc": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"content": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
}
}
}
}'
结果值返回:
{
"acknowledged": true, # 为 true 代表执行成功
"shards_acknowledged": true,
"index": "accounts"
}
这样,我们就成功的建立了一个名称为 kafei,类型为 article,里边包含三个字段 title、desc、content 的索引。
Elastic 的分词器称为 analyzer 。我们对每个字段指定分词器,我们来看看字段里边的设置:
"content": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
}
上面代码中,analyzer是字段文本的分词器,search_analyzer是搜索词的分词器。ik_max_word分词器是插件ik提供的,可以对文本进行最大数量的分词。
新增数据
在 Elastic 中添加数据,只需要向 localhost:9200/索引名称/类型名称 发送 PUT 请求,就可以新增一条记录:
# 向kafei索引中的类型article增加一条记录(指定添加记录的ID)
curl -X PUT 'localhost:9200/kafei/article/1' -H 'Content-Type: application/json' -d '
{
"title": "滴滴与软银成立合资公司,今年秋季将在日本上线打车功能",
"desc": "澎湃新闻消息",
"content": "澎湃新闻消息,网约车平台滴滴与日本投资集团软银成立了一家合资公司"
}'
返回数据:
{
"_index": "kafei",
"_type": "article",
"_id": "1",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
这是我们就成功的添加了一条数据,从我们的请求路径 /kafei/article/1 和添加成功之后返回的 _id: 1 这里可以看出,我们请求路径后边的 1 ,就是指定我们新增数据的ID值。
新增的时候,我们也可以不指定ID值,这时候就需要将 PUT 请求改成 POST 请求了:
# 向kafei索引中的类型article增加一条记录(不指定添加记录的ID)
curl -X POST 'localhost:9200/kafei/article' -H 'Content-Type: application/json' -d '
{
"title": "素颜别拍!摄影师超近距离抓拍土拨鼠爆笑瞬间",
"desc": "2018年7月19日消息",
"content": "2018年7月19日消息,野生动物摄影师在上陶恩山国家公园近距离抓拍一群土拨鼠"
}'
我们来看看返回值:
{
"_index": "kafei",
"_type": "article",
"_id": "NzB9smQBCKisClVkPjs3",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 0,
"_primary_term": 1
}
这时我们就可以看到这条记录的 _id 的数值是随机生成的一个字符串了。
查看数据
这时我们可以通过 GET 请求来查看我们新增的记录:
curl 'localhost:9200/kafei/article/1?pretty=true'
这里边的 URL 表示查看 ID 为 1 的记录,而 pretty=true 参数,则表示以易读的格式返回,结果如下:
<img src="https://pic4.zhimg.com/v2-0e59130aa7fc054c0bf9deaea77fb14b_b.jpg" data-caption="" data-size="normal" data-rawwidth="700" data-rawheight="176" class="origin_image zh-lightbox-thumb" width="700" data-original="https://pic4.zhimg.com/v2-0e59130aa7fc054c0bf9deaea77fb14b_r.jpg">
服务器返回的 Json 里边的 found 字段为 true 时,则表示查询成功,如果 ID 不正确,则查询不到数据:
<img src="https://pic4.zhimg.com/v2-932db8873848e432cdd0a0812d52c5af_b.jpg" data-caption="" data-size="normal" data-rawwidth="688" data-rawheight="107" class="origin_image zh-lightbox-thumb" width="688" data-original="https://pic4.zhimg.com/v2-932db8873848e432cdd0a0812d52c5af_r.jpg">
删除数据
我们可以使用 DELETE 请求来对我们无用的数据进行删除:
curl -X DELETE 'localhost:9200/kafei/article/1'
服务器返回的json数据:
{
"_index": "kafei",
"_type": "article",
"_id": "1",
"_version": 2,
"result": "deleted",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
我们通过 GET 请求查看一下这条记录,看是否被删除
<img src="https://pic2.zhimg.com/v2-931a7b9e0a972c00270c20fa2fe7f559_b.jpg" data-caption="" data-size="normal" data-rawwidth="659" data-rawheight="105" class="origin_image zh-lightbox-thumb" width="659" data-original="https://pic2.zhimg.com/v2-931a7b9e0a972c00270c20fa2fe7f559_r.jpg">
如此我们可以看出,我们的数据已经给删除了。
更新数据
更新数据跟新增数据是一样的,重复发送一个请求,后面的数据会覆盖前面的数据。为了方便查看,小编将 ID 为 1 的数据重新添加回来,然后再对这条数据进行更新操作:
# 更新ID为1的数据
curl -X PUT 'localhost:9200/kafei/article/1' -H 'Content-Type: application/json' -d '
{
"title": "滴滴与软银成立合资公司,今年秋季将在日本上线打车功能",
"desc": "网约车平台",
"content": "澎湃新闻消息,网约车平台滴滴与日本投资集团软银成立了一家合资公司"
}'
此时我们已经将 desc 字段的 “澎湃新闻消息”更新为“网约车平台”,执行之后如图所示:
<img src="https://pic4.zhimg.com/v2-b51372b8ab73827d8c1a39b6cdff7ef7_b.jpg" data-caption="" data-size="normal" data-rawwidth="751" data-rawheight="281" class="origin_image zh-lightbox-thumb" width="751" data-original="https://pic4.zhimg.com/v2-b51372b8ab73827d8c1a39b6cdff7ef7_r.jpg">
服务器返回的 Json 数据为:
{
"_index" : "kafei",
"_type" : "article",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 3,
"_primary_term" : 1
}
从上面的代码可以看出,result 字段变成了 updated,_version 字段也从 1 变成了 2,说明这次的操作是更新操作,不是新增操作,此时数据的版本为 2。
数据查询
全文查询
我们使用 GET 请求 localhost:9200/索引名称/类型名称/_search 请求,来查看我们所有的记录:
curl 'localhost:9200/kafei/article/_search?pretty=true'
# 返回的 JSON 数据
{
"took" : 5,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 1.0,
"hits" : [
{
"_index" : "kafei",
"_type" : "article",
"_id" : "NzB9smQBCKisClVkPjs3",
"_score" : 1.0,
"_source" : {
"title" : "素颜别拍!摄影师超近距离抓拍土拨鼠爆笑瞬间",
"desc" : "2018年7月19日消息",
"content" : "2018年7月19日消息,野生动物摄影师在上陶恩山国家公园近距离抓拍一群土拨鼠"
}
},
{
"_index" : "kafei",
"_type" : "article",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"title" : "瞄准中国出境游客,腾讯拟进军美国支付市场",
"desc" : "钛媒体瞬眼播报",
"content" : "【钛媒体瞬眼播报】外媒CNBC报道,腾讯的一名高管表示"
}
},
{
"_index" : "kafei",
"_type" : "article",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"title" : "滴滴与软银成立合资公司,今年秋季将在日本上线打车功能",
"desc" : "网约车平台",
"content" : "澎湃新闻消息,网约车平台滴滴与日本投资集团软银成立了一家合资公司"
}
}
]
}
}
我们来解析上边某些字段的意思:
took:表示操作耗时
timed_out:表示是否超时
total:返回的记录数
max_score:最高的匹配程度,本例是1.0。
hits:返回的记录组成的数组。
_score:表示每条记录的匹配程度
全文搜索
这里我们需要使用到 Elastic 的查询语法,要求 GET 请求带有数据体:
curl 'localhost:9200/kafei/article/_search?pretty=true' -H 'Content-Type: application/json' -d '
{
"query" : { "match" : { "content" : "消息" }}
}'
上面代码使用 Match 查询,指定的匹配条件是 content 字段里面包含 "消息" 这个词的数据。返回结果如下:
{
"took" : 67,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.2640665,
"hits" : [
{
"_index" : "kafei",
"_type" : "article",
"_id" : "NzB9smQBCKisClVkPjs3",
"_score" : 1.2640665,
"_source" : {
"title" : "素颜别拍!摄影师超近距离抓拍土拨鼠爆笑瞬间",
"desc" : "2018年7月19日消息",
"content" : "2018年7月19日消息,野生动物摄影师在上陶恩山国家公园近距离抓拍一群土拨鼠"
}
},
{
"_index" : "kafei",
"_type" : "article",
"_id" : "1",
"_score" : 0.5753642,
"_source" : {
"title" : "滴滴与软银成立合资公司,今年秋季将在日本上线打车功能",
"desc" : "网约车平台",
"content" : "澎湃新闻消息,网约车平台滴滴与日本投资集团软银成立了一家合资公司"
}
}
]
}
}
上面的结果显示,我们查到了“content”字段中包含“消息”的两条数据,我们可以通过 size 字段来设置返回结果的条数:
curl 'localhost:9200/kafei/article/_search?pretty=true' -H 'Content-Type: application/json' -d '
{
"query" : { "match" : { "content" : "消息" }},
"size": 1
}'
上面代码指定,每次只返回一条结果,我们还可以通过from字段,指定位移。
curl 'localhost:9200/kafei/article/_search?pretty=true' -H 'Content-Type: application/json' -d '
{
"query" : { "match" : { "content" : "消息" }},
"size": 1,
"from": 1
}'
from 跟 size 可以实现搜索的分页功能。
逻辑运算搜索
如果有多个搜索关键字, Elastic 认为它们是or关系。
curl 'localhost:9200/kafei/article/_search?pretty=true' -H 'Content-Type: application/json' -d '
{
"query" : { "match" : { "content" : "野生动物 网约车" }}
}'
上面的代码表示查询“content”中包含“野生动物”或者“网约车”的数据,结果如下:
{
"took" : 27,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 2.528133,
"hits" : [
{
"_index" : "kafei",
"_type" : "article",
"_id" : "NzB9smQBCKisClVkPjs3",
"_score" : 2.528133,
"_source" : {
"title" : "素颜别拍!摄影师超近距离抓拍土拨鼠爆笑瞬间",
"desc" : "2018年7月19日消息",
"content" : "2018年7月19日消息,野生动物摄影师在上陶恩山国家公园近距离抓拍一群土拨鼠"
}
},
{
"_index" : "kafei",
"_type" : "article",
"_id" : "1",
"_score" : 0.8630463,
"_source" : {
"title" : "滴滴与软银成立合资公司,今年秋季将在日本上线打车功能",
"desc" : "网约车平台",
"content" : "澎湃新闻消息,网约车平台滴滴与日本投资集团软银成立了一家合资公司"
}
}
]
}
}
使用 and 搜索:
curl 'localhost:9200/kafei/article/_search?pretty=true' -H 'Content-Type: application/json' -d '
{
"query": {
"bool": {
"must": [
{ "match": { "content": "消息" } },
{ "match": { "content": "网约车" } }
]
}
}
}'
这上边查找“content”中同时包含“消息”和“网约车”的消息,结果如下:
{
"took" : 18,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.4384105,
"hits" : [
{
"_index" : "kafei",
"_type" : "article",
"_id" : "1",
"_score" : 1.4384105,
"_source" : {
"title" : "滴滴与软银成立合资公司,今年秋季将在日本上线打车功能",
"desc" : "网约车平台",
"content" : "澎湃新闻消息,网约车平台滴滴与日本投资集团软银成立了一家合资公司"
}
}
]
}
}
总结
以上就是小编在 Linux 下耗时一天的时间来配置 Elasticsearch + analysis-ik 实现全文搜索的步骤,希望对大家能有所帮助。