文章目录
本文kibana操作es部分摘抄自:https://zhuanlan.zhihu.com/p/134104899
我的elasticsearch版本是7.9.1
这里首先分享一个超级超级给力的 postman 文件,关于es7.9.1版本的操作基本上面都有,地址:
https://anyongliang.oss-cn-beijing.aliyuncs.com/blog/web/file/es-7.9.1.json
打开地址,
复制里面的内容,
自己新建一个.json文件,
复制进去,
打开postman导入(import)那个.json文件,
然后就可以看到里面牛皮Plus的内容了!!!
放个截图你们感受一下
好的,开始正文…
一.什么是Elasticsearch
关于这个问题网络上有太多的答案了,我就不去一一的复制粘贴过来了,写一写自己的理解吧,如有错误,麻烦评论留(打)言(脸)…
- 它是RESTful 风格的搜索和数据分析引擎,底层引擎使用开源库Apache Lucene。
- Apache Lucene这玩意儿用起来太复杂了,所有就有了Elasticsearch,所以,偷懒使人进步…
- Elasticsearch还具备其他功能:
1.一个分布式的实时文档存储,每个字段可以被索引与搜索;
2.一个分布式实时分析搜索引擎;
3.能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据。
4.算法原理:倒排索引,b+树。
总结下来就是,这玩意简单,功能强大,不要问,问就好用
二.Elasticsearch使用相关安装
额…因为这里使记录elasticsearch的使用,所以安装这一块略去,大概说一下要安装的东西:
1.安装elasticsearch
2.要用elasticsearch,就必须要java,所以要安装java
3.安装 ElasticSearch head插件(这个不是必须装,装了的话用起来方便点),图形化管理es, 可以参考 [https://www.cnblogs.com/qiyu/p/12654883.html](https://www.cnblogs.com/qiyu/p/12654883.html
4.都安装那么多了,再装个kibana吧…
这里确实是我懒了,安装方面网上有很多教程,各种系统都能找到,所以要先安装一下
三.Elasticsearch相关概念
1.es是面向文档的,所以可以存储整个对象或者文档,它还可以索引每个文档里面的内容来进行搜索,可以对整个文档进行索引,搜索,排序和过滤。
来看一下es和mysql之间的对应大概对应关系
其实把类型tpye比做mysql中的tables表,是不对的,在elasticsearch7.0之后一个索引中只允许创建一个类型,如果想创建多个类型映射:
-
方法1:每个文档类型都有索引。
您可以在推特 微信索引 和 用户索引 中存储 微信,而不是在单个微信索引中存储 微信 和 用户。索引是完全独立的,因此在索引之间不会有字段类型冲突。
这种方法的好处:- 搜索更为精准,同一个索引中每一个文档都代表单个实体;
- 可以灵活分配索引空间,可以为用户索引分配较少的分片,为微信索引分配较多的分片;
-
方法2:在索引名称上动手脚
这个是我自己的办法,属于无奈之下的骚操作。
假设需要在es增加如下数据:
school数据库,里面有user表信息和student表信息,但是不可以创建两个type,所以就创建两个索引
1.school_user索引:存储school库里面的user表信息;
2.school_student索引:存储school库里面的student表信息;
ps:索引不能使用大写字母,都得是小写字母;
我描述的可能不太准确,大家看这个大佬的文章, https://elasticsearch.cn/article/337
下面对概念进行一些解释
-
索引-index,就是上方图中的indices
对应关系型数据库的中 库,一个索引由一个名字来标示(必须全部是小写字母), 对这个索引中内容进行操作时候,都要使用这个名字。 -
类型-type
一个索引可以定义一种或者多种类型,一个类型就是索引里面的一个逻辑分区,例如你把整个学生管理系统数据存储到一个索引中时,可以为学生定义一个类型,为老师定义一个类型,为课程再定义一个类型。 -
字段-field
就是数据表的字段,对不同内容进行分类标示。 -
映射-mapping
表结构定义,定义字段的各种属性。 -
文档-document
文档是一个可被索引的基础信息单元。你可以拥有一个产品的文档,一个用户的文档等等,文档以json格式来表示。 -
节点和集群
一个节点就是一个服务器,多个节点组成一个集群(之后再细说)。
四.开始操作
- 增删改查一个索引,打开postman,如图
- 增加索引
成功之后返回
- 增加索引
- 查索引
- 删除索引
- 用其他方式来操作,打开head(这个要先安装),看到下图,表示创建索引成功
- 使用kibana创建索引–PUT /movie_index
- 查询索引信息—GET /movie_index
- 删除索引–DELETE /movie_index
删除单独数据(document) DELETE /movie_index/movie/2
ps.多属性查询解释
bool 过滤可以用来合并多个过滤条件查询结果的布尔逻辑,它包含一下操作符:
- must:多个查询条件的完全匹配,相当于and;
- must_not:多个查询条件的相反匹配,相当于not;
- should:至少有一个查询条件匹配,相当于or.
五.kibana操作es增删改查
- 新增文档
创建索引并且指定mapping
PUT /xxxxxx
{
"settings": {
"number_of_shards": 8, #分片数
"number_of_replicas": 1 #备份数
},
"mappings": {
# type类型
"_doc":{
"properties":{
# 具体的字段值和字段类型
"ProductId":{
"type":"text",
"analyzer" : "ik_max_word", # 指定分词器为ik,需要预先安装
"index" : "true", # 指定当前字段可以被作为查询的条件
"store" : false # 是否需要额外存储
},
"EnterpriseName":{
"type":"text"
},
"CompanyId":{
"type":"text"
},
"ProductName":{
"type":"text"
},
"ProductModel":{
"type":"text"
}
}
}
}
}
添加数据: movie_index: 索引名,movie: 类型type名, 1: 文档名
PUT /movie_index/movie/1
{
"id":1,
"name":"operation red sea",
"doubanScore":8.5,
"actorList":[
{"id":1,"name":"zhang yi"},
{"id":2,"name":"hai qing"},
{"id":3,"name":"zhang han yu"}
]
}
PUT /movie_index/movie/2
{
"id":2,
"name":"operation meigong river",
"doubanScore":8.0,
"actorList":[
{"id":3,"name":"zhang han yu"}
]
}
PUT /movie_index/movie/3
{
"id":3,
"name":"incident red sea",
"doubanScore":5.0,
"actorList":[
{"id":4,"name":"zhang chen"}
]
}
- 搜索movie表的所有数据: GET/movie_index/movie/_search
得到回参
{
"took" : 528, //整个搜索请求花费多少毫秒
"timed_out" : false,
"_shards" : { //分片信息
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : { //命中信息
"total" : {
"value" : 3, //本次搜索,返回多少条结果
"relation" : "eq"
},
"max_score" : 1.0, //最大分数,关键字和搜索结果之间的匹配度
"hits" : [
{
"_index" : "movie_index", //索引
"_type" : "movie", //表
"_id" : "1", //文档
"_score" : 1.0, //匹配度, 命中分数
"_source" : { //查询的数据本身
"id" : 1,
"name" : "operation red sea",
"doubanScore" : 8.5,
"actorList" : [
{
"id" : 1,
"name" : "zhang yi"
},
{
"id" : 2,
"name" : "hai qing"
},
{
"id" : 3,
"name" : "zhang han yu"
}
]
}
},
{
"_index" : "movie_index",
"_type" : "movie",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"id" : 2,
"name" : "operation meigong river",
"doubanScore" : 8.0,
"actorList" : [
{
"id" : 3,
"name" : "zhang han yu"
}
]
}
},
{
"_index" : "movie_index",
"_type" : "movie",
"_id" : "3",
"_score" : 1.0,
"_source" : {
"id" : 3,
"name" : "incident red sea",
"doubanScore" : 5.0,
"actorList" : [
{
"id" : 4,
"name" : "zhang chen"
}
]
}
}
]
}
}
- 查找指定 id 的 document 数据: GET /movie_index/movie/1
- 按照字段分词进行查询
GET /movie_index/movie/_search
{
"query": {
"match":{
"name":"red"
}
}
}
得到回复参数
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 2,
"relation" : "eq"
},
"max_score" : 0.4700036, //这里就是匹配度了
"hits" : [
{
"_index" : "movie_index",
"_type" : "movie",
"_id" : "1",
"_score" : 0.4700036, //这里就是匹配度了
"_source" : {
"id" : 1,
"name" : "operation red sea",
"doubanScore" : 8.5,
"actorList" : [
{
"id" : 1,
"name" : "zhang yi"
},
{
"id" : 2,
"name" : "hai qing"
},
{
"id" : 3,
"name" : "zhang han yu"
}
]
}
},
{
"_index" : "movie_index",
"_type" : "movie",
"_id" : "3",
"_score" : 0.4700036, //这里就是匹配度了
"_source" : {
"id" : 3,
"name" : "incident red sea",
"doubanScore" : 5.0,
"actorList" : [
{
"id" : 4,
"name" : "zhang chen"
}
]
}
}
]
}
}
- 按照分词子属性查询
GET /movie_index/movie/_search
{
"query": {
"match": {
"actorList.name": "zhang"
}
}
}
- 按照短语查询
按照短语查询的意思是指, 匹配某个 field 的整个内容, 不再利用分词技术
把operation red作为一个整体来看待
GET /movie_index/movie/_search
{
"query": {
"match_phrase": {
"name": "operation red"
}
}
}
- 模糊查询
校正匹配分词,当一个单词都无法准确匹配,es 通过一种算法对非常接近的单词也给与一定的评分,能够查询出来,但是消耗更多的性能。
GET /movie_index/movie/_search
{
"query": {
"match": {
"字段名": {
"query": "模糊匹配的值",
"fuzziness": "AUTO",
"operator": "and"
}
}
}
}
多字段模糊搜索:
{
"query": {
"bool": {
"should": [ //should,或运算关系
{
"match": { //分词
"EnterpriseName": { //查询的字段
"query": "大理石", //查询的值
"fuzziness": "AUTO",
"operator": "and"
}
}
},
{
"match": {
"ProductName": {
"query": "大理石",
"fuzziness": "AUTO",
"operator": "and"
}
}
},
{
"match": {
"ProductModel": {
"query": "大理石",
"fuzziness": "AUTO",
"operator": "and"
}
}
}
]
}
}
}
这有一个大坑一定要注意,查询的字段mapping必须是text,不能是keyword,keyword的话是不会进行分词的,就是说不能进行模糊匹配!!!
那万一mapping已经定好了改不了怎么办?
重新创建一个,复制数据,然后更改别名…
步骤
- 查看老的索引的文档接口
GET 老索引名字/_mapping - 创建新索引 : 负责老索引的文档结构
PUT /新索引名字 - 迁移老的索引数据到新的索引
POST _reindex
{
"source": {
"index": "xxxx" #老的索引名字
},
"dest": {
"index": "aaasd" #新的索引名字
}
}
具体操作参考这里 https://blog.youkuaiyun.com/qq_30502699/article/details/104394973
- 过滤(查询后过滤)
GET /movie_index/movie/_search
{
"query": {
"match": {
"name": "red"
}
},
"post_filter": {
"term": {
"actorList.id": "3"
}
}
}
- 查询前过滤(推荐使用)
GET movie_index/movie/_search
{
"query": {
"bool": {
"filter": [
{"term":
{"actorList.id": 3}
},
{
"term":
{"actorList.id": 1}
}
],
"must":
{"match": {
"name": "zhang"
}}
}
}
}
- 按范围过滤
GET movie_index/movie/_search
{
"query": {
"bool": {
"filter": {
"range": {
"doubanScore": {
"gt": 5,
"lt": 9
}
}
}
}
}
}
gt : 大于
lt : 小于
gte : 大于等于
lte : 小于等于
- 排序
GET movie_index/movie/_search
{
"query":{
"match": {"name":"red operation"}
}
, "sort": [
{
"doubanScore": {
"order": "desc"
}
}
]
}
- 分页查询
GET movie_index/movie/_search
{
"query": { "match_all": {} },
"from": 1,
"size": 1
}
- 指定查询的字段
GET movie_index/movie/_search
{
"query": { "match_all": {} },
"_source": ["name", "doubanScore"]
}
- 聚合
//每个演员参演了多少部电影
GET movie_index/movie/_search
{
"aggs": {
"groupby_actor": {
"terms": {
"field": "actorList.name.keyword"
}
}
}
}
//每个演员参演电影的平均分是多少,并按评分排序
GET movie_index/movie/_search
{
"aggs": {
"groupby_actor_id": {
"terms": {
"field": "actorList.name.keyword" ,
"order": {
"avg_score": "desc"
}
},
"aggs": {
"avg_score":{
"avg": {
"field": "doubanScore"
}
}
}
}
}
}
- 修改 document
修改分两种: 整体替换和只修改某个字段
整体替换和新增文档没有区别
//整体替换
PUT /movie_index/movie/3
{
"id":"3",
"name":"incident red sea",
"doubanScore":"8.0",
"actorList":[
{"id":"1","name":"zhang chen"}
]
}
//只修改某个字段(使用post方法)
POST /movie_index/movie/3/_update
{
"doc": {
"doubanScore":"8.1"
}
}
六.elasticsearch分词
es是自带中文分词的,但是它默认不懂中文,没有词语的概念,如:默认分词分出来的是这样 :
“这茶叶比较贵”,
“这”,“茶”,“叶”,“比”,“较”,“贵”,
这种分法明显是不符合我们的需求的,我们希望得到
“这茶叶比较贵”,
“这”,“茶叶”,“比较”,“贵”,
所以我们要安装中文分词器。
在elasticsearch的目录下面,有一个叫plugins的目录,es会在这个目录里面扫描,里面的每一个目录都被认为是一个分词插件。
安装IK分词器
- 在plugins目录下创建目录 IK;
- 去github下载对应自己es版本的IK(目录名随意起),版本一定要和自己的es版本对应!https://github.com/medcl/elasticsearch-analysis-ik/releases
- 把下载的包里面的文件复制到刚刚创建的IK目录里面;
- 重启es;
- 验证是否成功
GET _analyze
{
"analyzer": "ik_smart",
"text":"这茶叶比较贵"
}
ik分词器主要是两个:
– ik_smart : 简单分词器,将以最小的组合拆分中文。
– ik_max_word : 最大化分词器,以多结果方式拆分中文。
操作正常的话,会返回这样的数据, 就是我们想要的结果。
{
"tokens" : [
{
"token" : "这",
"start_offset" : 0,
"end_offset" : 1,
"type" : "CN_CHAR",
"position" : 0
},
{
"token" : "茶叶",
"start_offset" : 1,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "比较",
"start_offset" : 3,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "贵",
"start_offset" : 5,
"end_offset" : 6,
"type" : "CN_CHAR",
"position" : 3
}
]
}
七.通过mapping指定字段属性
- 先看一下类型的对应关系:
true/false → boolean
1020 → long
20.1 → double
“2018-02-01” → date
“hello world” → text
分词和索引
1.索引 默认都建索引
2.分词 text
八.安装logstash
首先电脑java的版本得在1.8以上;
然后去官网下载logstash包,https://www.elastic.co/cn/downloads/logstash
一个java项目,不需要安装,直接解压执行即可。
测试logstash
- 解压logstash包之后,进入目录logstash-7.9.3/bin;(我下载的是7.9.3版本)
- 执行 .logstash -e ‘input { stdin { } } output { stdout {} }’
- 随便输入一个啥,比如hello,如果返回
{
"@timestamp" => 2020-11-06T12:31:13.266Z,
"message" => "hello",
"host" => "V_VZJYAN-MB0",
"@version" => "1"
}
那么说明可以用了。
九.使用logstash把mysql数据导入es
这里面坑真心多,一点一点来
- 下载最新的 logstash-integration-jdbc 包,https://github.com/logstash-plugins/logstash-integration-jdbc。我的logstash版本是7.9.3, 其他版本可能有出入
- 解压安装包,进入logstash-integration-jdbc包里面,编译得到gem文件
gem build logstash-integration-jdbc.gemspec - 把上面步骤得到的gem文件复制到 logstash 包的bin目录下, 安装最新的logstash-integration-jdbc。
./logstash-plugin install logstash-integration-jdbc-5.0.6.gem
windows的同学执行./logstash-plugin.bat - logstash是ruby写的,所以还得安装ruby… 链接https://www.jianshu.com/p/c073e6fc01f5
- 然后下载安装mysql驱动包 mysql-connector-java-5.1.45.jar。或者其他版本,自行下载…
- 进入logstash包的bin目录下,创建编写两个文件:
- to_mysql.sql
select * from employee; //sql语句自己写
- to_mysql.conf
input {
stdin {
}
jdbc {
# 数据库地址 端口 数据库名
jdbc_connection_string => "jdbc:mysql://localhost:3306/companydb?characterEncoding=UTF-8&useSSL=false"
# 数据库用户名
jdbc_user => "root"
# 数据库密码
jdbc_password => "*******"
# mysql java驱动地址
jdbc_driver_library => "/Users/afafa/Desktop/soft/mysql-connector-java-5.1.45.jar"
jdbc_driver_class => "com.mysql.jdbc.Driver"
jdbc_paging_enabled => "true"
jdbc_page_size => "50000"
# sql 语句文件路径
statement_filepath => "/Users/afafa/Desktop/soft/logstash-7.9.3/bin/to_mysql.sql"
# 定时字段 各字段含义(由左至右)分、时、天、月、年,全部为*默认含义为每分钟都更新
schedule => "* * * * *"
}
}
filter {
json {
source => "message"
remove_field => ["message"]
}
}
output {
elasticsearch {
hosts => ["127.0.0.1:9200"]
# index名称
index => "companydb"
# type名称
document_type => "employee"
# 文档_id
document_id => "%{id}"
}
stdout {
codec => json_lines
}
}
- 然后进入logstash包的bin目录下执行
./logstash -f to_mysql.conf,稍等片刻,没有报错的的话就可以去es里面查看数据了…