一、ES 是什么?
Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。作为 Elastic Stack 的核心,Elasticsearch 会集中存储您的数据,让您飞快完成搜索,微调相关性,进行强大的分析,并轻松缩放规模。
上述描述摘自官网,当你能看到我这篇文章的时候,脑海里应该对 ES 有一个初步的概念了,可以把它理解为把数据存放在内存中的 MySQL,它最主要的功能是海量数据实时检索,比起传统的关系型数据库的优点是,没有磁盘 IO 开销,因为索引数据大部分都是存在于内存中的,我们可以通过 ES 提供的 Rest API 像通过 SQL 语句查询关系型数据库中的数据一样,官方的描述是这种查询语言称为 DSL。
Elasticsearch 提供了一个完整的基于 JSON 的查询 DSL(领域特定语言)来定义查询。将查询 DSL 视为查询的 AST(抽象语法树),由两种类型的子句组成:
叶查询子句 > > 叶查询子句在特定字段中查找特定值,例如
match
,term
或range
查询。这些查询可以自己使用。复合查询子句 > > 复合查询子句包装其他叶查询或复合查询,用于以逻辑方式组合多个查询(例如
bool
ordis_max
查询),或改变它们的行为(例如constant_score
query)。DSL 使用文档 > > https://www.elastic.co/guide/en/elasticsearch/reference/7.17/query-dsl.html
二、Kibana 是什么?
Kibana 使您能够塑造数据并在 Elastic Stack 中导航。使用 Kibana,您可以:
- 搜索、观察和保护您的数据。 从发现文档到分析日志再到查找安全漏洞,Kibana 是您访问这些功能及更多功能的门户。
- 分析您的数据。 搜索隐藏的见解,可视化您在图表、仪表、地图、图形等中发现的内容,并将它们组合到仪表板中。
- 管理、监控和保护 Elastic Stack。 管理您的数据,监控 Elastic Stack 集群的健康状况,并控制哪些用户可以访问哪些功能。
- Kibana 文档:https://www.elastic.co/guide/en/kibana/current/introduction.html
可以将 Kibana 理解为方便我们发送 Rest API 请求的一个客户端,相当于专门为 ES 服务器打造的一个 Postman 。
三、安装ES 、 Kibana
安装前默认你的 Linux 已经具备了 docker、 docker-compose 环境,将下面的配置文件保存为名称是:docker-compose.yml 的文件。
version: '3.5'
services:
elasticsearch:
container_name: elasticsearch
build:
context: services/elasticsearch
args:
- ES_VER=7.5.0
ports:
- "9200:9200"
- "9300:9300"
environment:
ES_JAVA_OPTS: "-Xms512m -Xmx512m" #设置使用jvm内存大小
discovery.type: single-node #以单一节点模式启动
# ELASTIC_PASSWORD: 123456 #设置ES密码
privileged: true
volumes:
- ./data/elasticsearch/plugins/:/usr/share/elasticsearch/plugins/
- ./data/elasticsearch/:/usr/share/elasticsearch/data/
- ./logs/elasticsearch/:/usr/share/elasticsearch/logs/
- ./services/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
kibana:
container_name: kibana
build:
context: services/kibana
args:
- KIBANA_VER=7.5.0
ports:
- "5601:5601"
privileged: true
volumes:
- ./services/kibana/kibana.yml:/usr/share/kibana/config/kibana.yml
depends_on:
- elasticsearch
创建好文件后,在文件所属的目录下执行命令: docker-compose -f docker-compose.yml up -d (-d : 在后台所有启动服务, -f : 指定使用的Compose模板文件,默认为docker-compose.yml,可以多次指定。)我这里是安装的 7.5.0 的 ES 版本,Kibana 的版本与之对应,假设设置了 ES 密码,那么后续请求 ES 服务都需要带上身份验证信息,Kibana 也需要输入账户名、密码登录, 账户名默认为:elastic ,密码:yml 文件中设置的 ES 密码。
四、向 ES 导入 Demo 数据
访问部署 Kibana 的机器, ip:5601,进入 Kibana 首页,点击网页做下架的展开菜单栏图标,选择 Dev Tools 选项,打开后,在网页左侧可以编写 DSL 语句,向 ES 发送请求,右侧显示相应结果。执行的命令如下,将内容粘贴至 Kibana中,将光标放置在 :POST bank/_bulk 这一行,行尾右侧边栏回显示一个三角形和一个扳手图标,点击三角形发送请求保存数据。
POST bank/_bulk
# 粘贴这个网页中的文档数据在下方然后点击执行(感谢此作者):https://gitee.com/xlh_blog/common_content/blob/master/es%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE.json#
五、ES 入门测试
将以下文档创建名为:ES 7.5.postman_collection.json 的 JSON 文件,然后点击 Postman 左上角的 Import 按钮选中文件导入即可。
{
"info": {
"_postman_id": "34d02b44-25de-46e9-b4d2-c03f9e223ffd",
"name": "ES 7.5",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
"_exporter_id": "11045914"
},
"item": [
{
"name": "查看版本",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "http://localhost:9200",
"protocol": "http",
"host": [
"localhost"
],
"port": "9200"
}
},
"response": []
},
{
"name": "查看节点信息",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "http://localhost:9200/_cat/nodes",
"protocol": "http",
"host": [
"localhost"
],
"port": "9200",
"path": [
"_cat",
"nodes"
]
}
},
"response": []
},
{
"name": "查看主节点信息",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "http://localhost:9200/_cat/master",
"protocol": "http",
"host": [
"localhost"
],
"port": "9200",
"path": [
"_cat",
"master"
]
}
},
"response": []
},
{
"name": "查看所有索引",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "http://localhost:9200/_cat/indices",
"protocol": "http",
"host": [
"localhost"
],
"port": "9200",
"path": [
"_cat",
"indices"
]
}
},
"response": []
},
{
"name": "PUT指定ID保存",
"request": {
"method": "PUT",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"name\" : \"jack\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "http://localhost:9200/student/one/1",
"protocol": "http",
"host": [
"localhost"
],
"port": "9200",
"path": [
"student",
"one",
"1"
]
}
},
"response": []
},
{
"name": "POST保存",
"request": {
"method": "POST",
"header": [],
"body": {
"mode": "raw",
"raw": "{\n \"name\" : \"jack1\"\n}",
"options": {
"raw": {
"language": "json"
}
}
},
"url": {
"raw": "http://localhost:9200/student/one/q1eYgIUBGSRCIL0j0d7A",
"protocol": "http",
"host": [
"localhost"
],
"port": "9200",
"path": [
"student",
"one",
"q1eYgIUBGSRCIL0j0d7A"
]
},
"description": "可自动生成ID/指定ID相当于修改,PUT必须指定ID"
},
"response": []
},
{
"name": "根据ID查询数据",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "http://localhost:9200/student/one/1",
"protocol": "http",
"host": [
"localhost"
],
"port": "9200",
"path": [
"student",
"one",
"1"
]
}
},
"response": []
},
{
"name": "删除指定ID数据",
"request": {
"method": "DELETE",
"header": [],
"url": {
"raw": "http://localhost:9200/student/one/1",
"protocol": "http",
"host": [
"localhost"
],
"port": "9200",
"path": [
"student",
"one",
"1"
]
}
},
"response": []
},
{
"name": "删除索引",
"request": {
"method": "DELETE",
"header": [],
"url": {
"raw": "http://localhost:9200/student",
"protocol": "http",
"host": [
"localhost"
],
"port": "9200",
"path": [
"student"
]
}
},
"response": []
}
]
}
六、ES 基础请求 DSL
以下执行语句请在 Kibana 的 Dev Tools 中执行
## 查询所有
GET bank/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"account_number": "desc"
},
{
"balance": "asc"
}
],
"from": 0,
"size": 20,
"_source": ["balance","firstname"]
}
## 全文检索:会将查询条件分词,任意一个匹配都算匹配
GET bank/_search
{
"query": {
"match": {
"address": "mail one"
}
}
}
## 短语匹配:不会将查询条件分词,作为一个完整的词去搜索
## 也可以使用字段.keyword 精确匹配,必须是值和搜索值完全相等
GET bank/_search
{
"query": {
"match_phrase": {
"address": "mail one"
}
}
}
## 多字段匹配,多个字段任意匹配,会分词查询
GET bank/_search
{
"query": {
"multi_match": {
"query": "mill one",
"fields": ["address","firstname"]
}
}
}
## bool 复合查询,条件都要满足 and
## must:数组中的条件都要满足 must_not:都不满足 should == or 不是必须满足
GET bank/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"address": "mill"
}
},
{
"match_phrase": {
"firstname": "mill"
}
}
],
"must_not": [
{
"match": {
"address": "abc"
}
}
],
"should": [
{
"match": {
"FIELD": "TEXT"
}
}
]
}
}
}
## filter:筛选结果,不计算相关性得分
GET bank/_search
{
"query": {
"bool": {
"filter": {
"range": {
"age": {
"gte": 10,
"lte": 20
}
}
}
}
}
}
## 非文本字段检索推荐term
GET bank/_search
{
"query": {
"term": {
"age": {
"value": 28
}
}
}
}
## 搜索address中包含mi1l的所有人的年龄分布以及平均年龄
GET bank/_search
{
"query": {
"match": {
"address": "mill"
}
},
"aggs": {
"ageAgg": {
"terms": {
"field": "age",
"size": 10
}
},
"ageAvg": {
"avg": {
"field": "age"
}
}
}
}
## 按照年龄聚合,并且请求这些年龄段的这些人的平均薪资
GET bank/_search
{
"query": {
"match_all": {}
},
"aggs": {
"ageAgg": {
"terms": {
"field": "age"
},
"aggs": {
"balanceAvg": {
"avg": {
"field": "balance"
}
}
}
}
},
"size": 0
}
## 查出所有年龄分布,并且这些年龄段中M的平均薪资和F的平均薪资以及这个年龄段的总体平均薪资
GET bank/_search
{
"query": {
"match_all": {}
},
"aggs": {
"ageAgg": {
"terms": {
"field": "age"
},
"aggs": {
"balanceAvg" :{
"avg": {
"field": "balance"
}
},
"genderAgg": {
"terms": {
"field": "gender.keyword",
"size": 10
},
"aggs": {
"genderBalanceAvg": {
"avg": {
"field": "balance"
}
}
}
}
}
}
},
"size": 0
}
## 新建索引时指定字段类型
PUT /my-index
{
"mappings": {
"properties": {
"age": { "type": "integer" },
"email": { "type": "keyword" },
"name": { "type": "text" }
}
}
}
## 新建索引后添加字段映射,index:false 不参与搜索
PUT /my-index/_mapping
{
"properties" : {
"id" : {
"type" : "long",
"index" : false
}
}
}
## 查看索引字段类型
GET my-index/_mapping
## es指定好映射规则后不允许修改,想要修改只能创建一个新的索引,然后把原有的数据迁移到新索引
GET bank/_mapping
## 创建新索引 指定映射关系
PUT /bank1/
{
"mappings": {
"properties" : {
"account_number" : {
"type" : "long"
},
"address" : {
"type" : "text"
},
"age" : {
"type" : "long"
},
"balance" : {
"type" : "long"
},
"city" : {
"type" : "keyword"
},
"email" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"employer" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"firstname" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"gender" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"lastname" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"state" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
}
}
}
}
## 迁移数据到新索引中
POST _reindex
{
"source": {
"index": "bank",
"type": "account"
},
"dest": {
"index": "bank1"
}
}
GET /bank1/_search
{
"query" : {
"match_all" :{}
}
}
## 使用默认分词器进行分词 (仅支持英文)
POST _analyze
{
"analyzer": "standard",
"text": "加油努力."
}
## 使用IK分词器分词 ik_smart: 会做最粗粒度的拆分,适合 Phrase 查询。
POST _analyze
{
"analyzer": "ik_smart",
"text": "加油努力."
}
## ik_max_word: 会将文本做最细粒度的拆分,会穷尽各种可能的组合,适合 Term Query;
POST _analyze
{
"analyzer": "ik_max_word",
"text": "加油努力."
}
## 发起批量保存请求
POST my-index/_bulk
{"index":{"_id":"1"}}
{"age" : 1, "email" : "12345@qq.com", "id" : "1", "name" : "张三"}
{"index":{"_id":"2"}}
{"age" : 21, "email" : "12345@qq.com", "id" : "2", "name" : "李四"}
七、相关文档链接
-
elasticsearch-analysis-ik :IK分词器,安装了这个才支持对中文进行分词,下载与 ES 对应版本的 Releases 包,解压后放置在 ES 的 plugins 目录下重启 ES 即可。
-
elasticsearch-head :Elasticsearch 集群的可视化 Web 前端,相当于 Navicat 操作 MySQL。
-
ES 官方文档 :英文好的同学可以直接翻阅官方文档学习 ES。