【实战】手把手教你使用 Elasticsearch 实现海量级数据搜索(上
一、简介
Elasticsearch(简称ES)是一个基于Apache Lucene™的开源搜索引擎,无论在开源还是专有领域,Lucene 可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。
对于初次接触 Elasticsearch,不禁会发出一个疑问,Elasticsearch 是干啥的?
官方的解释如下:Elasticsearch(简称ES)是一个基于 Apache Lucene™ 的开源搜索引擎,它提供了一个基于 RESTful web 接口的分布式多用户能力的全文搜索引擎,能够达到实时搜索、稳定、可靠、快速、安装使用方便等特点。
Elasticsearch 的底层数据存储和搜索,是基于 Lucene 进行开发的,那 Lucene 又是啥呢?
Lucene 是 java 领域迄今为止最先进、性能最好的、功能最全的搜索引擎库。
如果你之前了解过或者使用过 Lucene,那么在学习 Elasticsearch 会非常的容易,甚至你会发现很多的 Elasticsearch 的 查询语法和 Lucene 的查询语法有很多的相似之处。
今天我们主要是介绍 Elasticsearch 的用法,在后续的文章中,我们也会给大家介绍 Lucene 的玩法。
在介绍 Elasticsearch 的 RESTful API 之前,我们先简单的了解一下 Elasticsearch 中几个重要的概念。
• 索引 (indices ):类似于我们的关系型数据库
• 类型(type ):类似于数据库的表结构
• 文档(Document ):类似于数据库表中的行,也就是具体的数据
• 字段(Field ):雷雨时数据库表中的列
不过,这里有一个非常坑的地方,es 版本号的不同,其中的内部结构和对外的 API 差别也很大,各版本号差别如下:
• es5 版本:允许一个索引库下中可以创建多个类型
• es6 版本:一个索引库下中只能创建一种类型
• es7 版本:一个索引库不支持显式创建类型,当创建索引的时候,默认会创建一个名称为_doc的类型
为什么在高版本里面,es 不支持创建多个类型呢?
因为一个索引库下,如果多个类型,会存在搜索问题,比如,类型 A 下某个字段order_source是一个long型;类型 B 下,字段order_source是一个text型。
这两个字段名称都是一样,实际存入 Lucene 中,也是同一个字段,但是他们的字段类型是不一样的,要么是long型,要么是text型,只会是其中一个,这就造成一个问题,类型 A 中order_source字段不可用,或者类型 B 中order_source字段不可用。
因此,在新版本中,索引下的类型,有且只有一个!
了解了 Elasticsearch 的基本概念之后,下面我们一起开启 Elasticsearch 实战操作!
二、服务安装
首先,在使用 Elasticsearch 之前,我们需要先安装好服务,操作也很简单。
为了和真实环境一致,我们采用CentOS7来部署 ElasticSearch 服务。
建议把所需的安装包,手动从网上下载下来,因为服务器下载 ElasticSearch 安装包速度像蜗牛……,非常非常慢~~,可能是国内的网络原因吧!
登录https://www.elastic.co/cn/downloads/elasticsearch,选择相应的系统环境下载软件包,小编我采用的是CentOS,所以选择Linux环境。
2.1、安装JDK(已经安装过,可以跳过)
Elasticsearch 是用 Java 语言开发的,所以在安装之前,需要先安装一下JDK
yum -y install java-1.8.0-openjdk
查看java安装情况
java -version
2.2、安装ElasticSearch
进入到对应上传的文件夹,安装ElasticSearch
rpm -ivh elasticsearch-6.1.0.rpm
查找安装路径
rpm -ql elasticsearch
一般是装在/usr/share/elasticsearch/下。
2.3、设置data的目录
创建/data/es-data目录,用于elasticsearch数据的存放
mkdir -p /data/es-data
修改该目录的拥有者为elasticsearch
chown -R elasticsearch:elasticsearch /data/es-data
2.4、设置log的目录
mkdir -p /log/es-log
修改该目录的拥有者为elasticsearch
chown -R elasticsearch:elasticsearch /log/es-log
2.5、修改配置文件elasticsearch.yml
vim /etc/elasticsearch/elasticsearch.yml
修改如下内容:
#设置节点名称
cluster.name: my-es
#设置data存放的路径为/data/es-data
path.data: /data/es-data
#设置logs日志的路径为/log/es-log
path.logs: /log/es-log
#设置内存不使用交换分区,配置了bootstrap.memory_lock为true时反而会引发9200不会被监听,原因不明
bootstrap.memory_lock: false
#设置允许所有ip可以连接该elasticsearch
network.host: 0.0.0.0
#开启监听的端口为9200
http.port: 9200
#增加新的参数,为了让elasticsearch-head插件可以访问es (5.x版本,如果没有可以自己手动加)
http.cors.enabled: true
http.cors.allow-origin: "*"
2.6、启动elasticsearch
启动
systemctl start elasticsearch
查看状态
systemctl status elasticsearch
设置开机启动
systemctl enable elasticsearch
启动成功之后,测试服务是否开启
curl -X GET http://localhost:9200
返回如下信息,说明安装、启动成功了
同时也可以远程测试一下,如果网络被拒绝,检查防火墙是否开启
#查询防火墙状态
firewall-cmd --state
如果状态是active表示已经开启,可以将其关闭
#关闭防火墙
systemctl stop firewalld.service
如果不想开机启动,可以输入如下命令
#禁止firewall开机启动
systemctl disable firewalld.service
我们再来测试一下远程是否可以正常访问,结果如下:
已经可以正常访问了。
三、可视化界面管理
Elasticsearch 服务安装完成之后,有没有工具,可以通过页面管理直接查询呢?
答案肯定是有的,以chrome为例,访问https://chrome.google.com/webstore/detail/elasticsearch-head/ffmkiejjmecolpfloofpjologoblkegm?hl=zh-CN这个地址,在线安装ElasticSearch Head插件,也可以在先下载这个插件,然后离线安装。
打开ElasticSearch Head插件,输入 Elsaticsearch 服务器的地址,然后连接,就可以可视化查看 es 内部存储的数据了
四、索引 API 介绍
下面以 ElasticSearch 的6.8.2版本为例,给大家介绍 API 的使用。
4.1、创建索引
Elsaticsearch 创建索引非常的简单,通过put方式,只需要填写好地址就可以创建,以创建一个user_index索引为例,请求方式如下:
4.2、查询索引
通过get请求,就可以直接获取当前索引信息。
4.3、删除索引
通过delete请求,就可以直接删除索引信息。
4.4、创建类型
如果我们想要在索引下创建类型,可以通过如下方式实现。
例如,在索引下创建一个名为user_type的类型,字段映射结构如下:
{
"properties":{
"name":{
"type":"text",
"index":true
},
"sex":{
"type":"keyword",
"index":true
},
"mobile":{
"type":"keyword",
"index":false
}
}
}
4.5、查询类型
将put请求改成get,就可以查询我们刚刚创建的类型了。
详细的内容如下:
{
"user_index": {
"mappings": {
"user_type": {
"properties": {
"mobile": {
"type": "keyword",
"index": false
},
"name": {
"type": "text"
},
"sex": {
"type": "keyword"
}
}
}
}
}
}
Elasticsearch 支持的数据类型非常的多,本文只使用字符串型的text和keyword,其中text类型支持分词,而keyword不支持分词查询,在实际的使用过程中,大家根据自己的业务情况,对数据类型采用合适的值。
四、文档 API 介绍
Elasticsearch 使用最频繁的部分,当属文档 API 操作,下面我们一起来看看具体的实践。
4.1、创建文档
通过 restful 方式创建,其中末尾可以指定主键 ID,多次执行如果 主键ID 存在就更新,否则插入。
4.2、通过主键 ID 查询文档
只需要将post改成get即可!
4.3、更新文档(指定字段)
在url末尾加上_update,就可以执行修改请求!
4.4、通过主键 ID 删除文档
将请求类型改成delete,就可以删除文档!
4.5、查询文档-查询所有
在url后面加上_search,就可以查询所有文档数据
4.6、查询文档-返回指定列
通过在请求参数中配置"_source" : [字段1,字段2],可以返回指定列。
请求参数如下:
{
"query" : {
"match_all" : {
}
},
"_source" : ["name","sex"]
}
返回结构,和上面类似!
4.7、查询文档-字段排序
通过在请求参数中配置sort,可以对字段内容进行排序返回。
请求参数如下:
{
"query" : {
"match_all" : {
}
},
"sort" : {
"_id":{
"order" : "asc"
}
}
}
返回结构,和上面类似!
4.8、查询文档-分页查询
通过在请求参数中配置from和size,就可以进行分页查询了。
• from:表示第几行,默认从0开始
• size:表示返回多少数据
请求参数如下:
{
"query" : {
"match_all" : {
}
},
"from" : 0,
"size" : 2
}
4.9、查询文档-某个字段精准匹配查询
通过match可以实现对字段内容的查询。
请求参数如下:
{
"query" : {
"match" : {
"name" : "张里"
}
}
}
4.10、查询文档-多条件查询 - and
如果需要多个条件组合查询,可以通过bool和must结合查询
{
"query":{
"bool":{
"must":[
{
"match":{
"name":"张"
}
},
{
"match":{
"sex:"男"
}
}
]
}
}
}
4.11、查询文档-多条件查询 - or
如果需要多个条件组合查询,可以通过bool和should结合查询
{
"query":{
"bool":{
"should":[
{
"match":{
"name":"张"
}
},
{
"match":{
"sex:"男"
}
}
]
}
}
}
4.12、查询文档-多条件查询 - 大于/小于
如果需要多个条件组合查询,可以通过bool配置实现filter -> range关系查询
{
"query":{
"bool":{
"filter":{
"range":{
"age":{
"gt" : 25,
"lt" : 50
}
}
}
}
}
}
4.13、查询文档-聚合查询 - group by
可以通过aggs -> terms实现对某个字段进行聚合查询,比如下面这个配置,查询具有相同年龄的用户数。
{
"aggs":{
"age_group":{
"terms":{
"field":"age"
}
}
},
"size" : 0
}
4.14、查询文档-聚合查询 - avg
可以通过aggs -> avg实现对某个字段进行聚合查询,比如下面这个配置,查询具有用户的年龄平均值。
{
"aggs" : { //聚合操作
"age_avf" : { //名称,自定义
"avg" : { //分组
"field" : "age" //分组字段
}
}
},
"size" : 0
}
4.15、查询文档-聚合查询 - sum
可以通过aggs -> sum实现对某个字段进行聚合查询,比如下面这个配置,查询具有用户的年龄总数。
{
"aggs" : { //聚合操作
"age_sum" : { //名称,自定义
"sum" : { //分组
"field" : "age" //分组字段
}
}
},
"size" : 0
}
五、小结
本文主要是围绕 ElsaticSearch 的 restful api 做了一个简单的介绍,在下篇文章中,我们会重点介绍 SpringBoot 整合 ElsaticSearch 的实战玩法。
内容难免有所遗漏,欢迎大家批评指出!
本文转载自公共号Java极客技术。