【ES数据库】Elasticsearch安装使用

一、简介

  • ElasticsearchMongoDB/Redis类似,是非关系型数据库,从索引文档到文档能被搜索到只有一个轻微的延迟,是采用Restful API标准的可扩展和高可用的实时数据分析的全文搜索工具
  • Elastic Search的实现原理是,利用内置分词器(Analyzer)对数据库文本进行分词,将解析出的关键词和数据库文档建立倒排索引。输入的搜索文本也会进行分词,通过倒排索引找到匹配的数据库文本。之后使用 TF-IDF算法,根据相关度对每个匹配的文本进行评分排序,返回搜索结果。
    在这里插入图片描述

二、ES数据库特性

  • 可拓展:支持一主多从且扩容简易,只要cluster.name一致且在同一个网络中就能自动加入当前集群;本身就是开源软件,也支持很多开源的第三方插件
  • 高可用:在一个集群(Cluster)多个节点(Node)中分布式存储,索引(Index)支持分片(Shards)和复制(Replicas),即使部分节点down掉,也能自动进行数据恢复和主从切换
  • 采用RestfulAPI标准:通过http接口使用JSON格式进行操作数据;数据存储的最小单位是文档,本质上是一个JSON 文本

三、与关系型数据库的区别

  • 索引 Index:一个拥有几分相似特征的文档的集合
  • 类型 Type:索引可以为拥有相同字段的文档定义一个类型;个索引中可以创建多个Type
  • 文档 Document:一个文档是一个可被索引的基础信息单元
  • 字段 Field:Elasticsearch的最小单位,相当于数据某一列
  • 映射 Mapping:所有的文档在写进索引之前都需要进行分析,如何将输入的文本分隔为词条,哪些词条又会被过滤,这种行为叫做映射,一般由用户自己定义相应的规则
SQL数据库(MySQL)NoSQL数据库(ES)
数据库 Database索引 Index
表 Table类型 Type
数据行 Row文档 Document
数据列 Column字段 Field

四、ELK搭建

ELK = elasticsearch + logstash + kibana
ELK常作为大型分布式系统的日志分析收集处理的解决方案:

  • ElasticSearch是一个基于Lucene基础上构建的开源搜索工具,具备实时性、分布式、可扩展等优点,并对Lucene进行了封装,开发者通过RESTful API即可实现对数据的搜索;
  • logstash是一个用于日志搜集, 分析, 过滤的工具. client端一般部署在用于搜集日志的主机上, server端负责将接收的到日志进行过滤, 然后转发到elasticsearch上;
  • kibana是一个用于汇总分析和搜索日志的工具, 可以为elasticsearch和logstash提供友好的日志分析的web界面;

在docker上搭建ELK,完成非关系型数据库的构建

  1. docker安装教程:Install Docker Engine on CentOS
  2. ELK搭建教程:基于腾讯云服务器安装ELK

常见问题

1. 生成注册令牌

连接 Kibana 实例或在安全的 Elasticsearch 集群中注册其他节点。
使用 elasticsearch-create-enrollment-token 工具创建注册令牌。

2. 页面数据查询报406错误

ES-Head需要Restful接口

{"error":"Content-Type header [application/x-www-form-urlencoded] is not supported","status":406}

解决方法:

  • 进入docker容器
# 命令 docker exec -it 容器ID /bin/bash
[root@localhost ~]# docker exec -it es-head /bin/bash
  • cd进入_site/目录,编辑vendor.js
[root@localhost ~]# vim _site/vendor.js

# 6886行: contentType: “application/x-www-form-urlencoded改成
# contentType: "application/json;charset=UTF-8"

# 7573行: var inspectData = s.contentType === “application/x-www-form-urlencoded” && 改成
# var inspectData = s.contentType === "application/json;charset=UTF-8" &&
3. kibana Unable to connect to Elasticsearch at http://elasticsearch:9200

重启elk服务后,需要在kibana修改es的ip

解决方法:

  • 进入docker容器
# 命令 docker exec -it 容器ID /bin/bash
[root@localhost ~]# docker exec -it es-head /bin/bash
  • kibana的配置文件出了问题,所以要修改配置文件,找到kibana.yml,进入修改
vim  /etc/kibana/kibana.yml
# 将elasticsearch改为自己的ip
  • 重启kibana

五、ES基本操作

1. ES数据库建立
  • 把所有字段设置为 "index": "not_analyzed"
  • _source 打开,不用零散存储每个字段,更高效
  • _all 关闭,因为检索是基于 k=v 这样字段已知的查询的
{
    "properties":{
        "属性": {
            "index": "not_analyzed",
            "type": "类型"
        }
    }
    "_source": {
        "enabled": true
    }, 
    "_all": {
        "enabled": false
    }
}

2. ES索引相关操作
添加索引
  • 请求形式 PUT
  • Content-Type: application/json
  • URL: http://{ELK服务地址}:9200/{索引名称}
{
    "settings":{
        "index":{
            "number_of_shards":"2", // 分片
            "number_of_replicas":"0", // 副本数
        }
    }
}
删除索引
  • 请求形式 DELETE
  • Content-Type: application/json
  • URL: http://{ELK服务地址}:9200/{索引名称}
3. ES文档相关操作
添加文档
  • 请求形式 POST
  • Content-Type: application/json
  • URL: http://{ELK服务地址}:9200/{索引名称}/{类型}/{id}
    /* id不是必填项,如果不传,ES会给一个默认值 */
{
    // 创建的文档数据内容
    "属性1": "值1",
    "属性2": "值2",
    "属性3": "值3 ",
    "属性4": "值4"
    ......
}
更新文档(局部更新)
  • 请求形式 POST
  • Content-Type: application/json
  • URL: http://{ELK服务地址}:9200/{索引名称}/{类型}/{id}/_update
    /* id是必填项 */
{
    // 更新的局部数据内容
    // doc作为键的数据json串
    "doc": {
        "属性1": "值1",
        "属性2": "值2"
        .....
    }
}
删除文档
  • 请求形式 DELETE
  • Content-Type: application/json
  • URL: http://{ELK服务地址}:9200/{索引名称}/{类型}/{id}
    /* id是必填项 */
查询文档
/* 简易查询 */
请求形式 GET
Content-Type: application/json

/* 通过id查询,返回文档全部字段 */
URL:  http://{ELK服务地址}:9200/{索引名称}/{类型}/{id}

/* 通过id查询,只返回文档特定字段 */
URL:  http://{ELK服务地址}:9200/{索引名称}/{类型}/{id}/_source?source=字段1,字段2

/* 全量查找,返回类型全部数据 */
URL:  http://{ELK服务地址}:9200/{索引名称}/{类型}/_search

/* 简易条件查询,返回类型中符合条件的文档 */
URL:  http://{ELK服务地址}:9200/{索引名称}/{类型}/_search?q=条件{字段: 值}


/* DSL搜索 */
请求形式 POST
Content-Type: application/json
URL:  http://{ELK服务地址}:9200/{索引名称}/{类型}/_search

/* 例如:查询年龄为34的用户数据 */
JSON
{
    "query": {
        "match": {
            "age": 34
        }
    }
}

/* 例如:查询年龄大于26岁且性别为男的用户数据 */
JSON
{
    "query": {
        "bool": {
            "filter": {
                "range": {
                    "age": {
                        "gt": 26
                    }
                }
            },
            "must": {
                "match": {
                    "sex": "男"
                }
            }
        }
    }
}

/* 例如:查询名字为魏大勇和秀琴的用户信息 */
JSON
{
    "query": {
        "match": {
            "name": "魏大勇 秀琴"
        }
    }
}

/* 查询结果高亮显示 */
/* 例如:查询名称为张三的用户数据 */
{
    "query": {
        "match": {
            "name": "张三"
        }
    },
    "highlight": {
        "fields": {
            "name": {}
        }
    }
}

/* 聚合操作(类似分组操作)*/
/* 例如:查询各个年龄的用户数 */
{
    "aggs": {
        "all_interests": {
            "terms": {
                "field": "age.keyword"
            }
        }
    }
}
4. 元数据操作

文档 (document) 的元数据(Metedata)

  • _index
    • document 存储在哪个 index 中
    • 类似的文档(document)放在同一个 index ,不同类型的文档放在不同的 index
    • index 名称必须小写,不用下划线(_)开头,不含逗号
  • _type
    • 代表 document 属于 index 下的哪个类型(type)
    • 一个 index 通常包含多个 type
    • type 名称可大小写,不用下划线(_)开头,不含逗号
  • _id
    • 代表 document 唯一标识,与index和type一起确定一个唯一的document
    • id 生成方式
      • 手动指定:PUT /index/type/id
      • 自动生成: PUT /index/type/ (base64编码20长度字符串,分布式集群下不可能重复)
  • _score
    • 相关度分数:匹配程度,分数越高越相关
查询响应

返回结果做JSON格式化操作

  • 请求形式 GET POST
  • 参数:?pretty // url结尾加上参数
  • URL: http://{ELK服务地址}:9200/{索引名称}/{类型}/{id}?pretty
判断某个文档是否存在,不查询它的内容
  • 请求形式 HEAD
  • URL: http://{ELK服务地址}:9200/{索引名称}/{类型}/{id}
  • 返回: 200 OK; 404 Not Found
批量查询
/* 例如:查询id为1002和1003的文档数据 */
请求形式 POST
参数:_mget // url结尾加上参数
URL: http://{ELK服务地址}:9200/{索引名称}/{类型}/_mget

JSON
{
    "ids":["1002","1003"]
}
批量添加
请求形式 POST
参数:_bulk // url结尾加上参数
URL: http://{ELK服务地址}:9200/{索引名称}/{类型}/_bulk

JSON // 注意:每条数据后需要加换行,最后一行也要加
{action:{metedata}}\n
{source body}\n
{action:{metedata}}\n
{source body}\n
......

/* 例如:新增三条数据 */
{"create":{"_index":"{索引名称}","_type":"{类型}","_id":"{id_1}"}}
{"id":"1006","name":"user001","age":20,"sex":"男"}
{"create":{"_index":"{索引名称}","_type":"{类型}","_id":"{id_2}"}}
{"id":"1007","name":"user002","age":30,"sex":"男"}
{"create":{"_index":"{索引名称}","_type":"{类型}","_id":"{id_3}"}}
{"id":"1008","name":"user003","age":40,"sex":"女"}

/* 例如:批量删除三条数据 */
{"delete":{"_index":"{索引名称}","_type":"{类型}","_id":"{id_1}"}}
{"delete":{"_index":"{索引名称}","_type":"{类型}","_id":"{id_2}"}}
{"delete":{"_index":"{索引名称}","_type":"{类型}","_id":"{id_3}"}}
5. 分页操作

ES搜索默认最多返回10条数据,需要分页返回

请求形式 POST
参数: ?size=n1&from=n2
    size: 每页显示的结果数量
    from: 跳过多少结果数
URL: http://{ELK服务地址}:9200/{索引名称}/{类型}/_search?size=3&from=0

/* 每页显示四条数据,显示第二页 */
URL: http://{ELK服务地址}:9200/{索引名称}/{类型}/_search?size=4&from=4
6. 映射操作

如果没有指定字段类型,ES会默认给字段赋上相应类型

ES支持的基本数据类型:

  • 字符串:
    • text:存储数据时,会自动分词,并生成索引
    • keyword:存储数据时,不会分词,直接整个词去建索引
  • 整数 : byte, short, integer, long
  • 浮点数 : float、double
  • 布尔型 : boolean
  • 日期 : date
/* 创建索引的映射信息 */
请求形式 PUT
URL: http://{ELK服务地址}:9200/{索引名称}

JSON
{
    "settings": {
        "index": {
            "number_of_shards": 2,
            "number_of_replicas": 0
        }
    },
    "mappings": {
        "properties": {
            "name": {
                "type": "text"
            },
            "age": {
                "type": "integer"
            },
            "email": {
                "type": "keyword"
            },
            "hobby": {
                "type": "text"
            }
        }
    }
}

/* 查询索引的映射信息 */
请求形式 GET
参数: _mapping
URL: http://{ELK服务地址}:9200/{索引名称}/_mapping
7. 结构化查询
/* term查询 - 用于精确匹配某些值 */
请求形式 POST
URL: http://{ELK服务地址}:9200/{索引名称}/{类型}/_search
/* 例如:查询年龄为26的数据信息 */
JSON
{
    "query": {
        "term": {
            "age": 26
        }
    }
}


/* terms查询 - 和term类似,但terms允许指定多个匹配条件 */
/* 某个字段指定了多个值,那么文档需要一起去匹配 */
请求形式 POST
URL: http://{ELK服务地址}:9200/{索引名称}/{类型}/_search
/* 例如:查询年龄为26和30的用户数据信息 */
JSON
{
    "query": {
        "term": {
            "age": [26, 30]
        }
    }
}

/* range查询 - 允许按照指定的范围查找数据 */
请求形式 POST
范围操作符:
    gt:大于
    gte:大于等于
    lt:小于
    lte:小于等于
URL: http://{ELK服务地址}:9200/{索引名称}/{类型}/_search
/* 例如:查询年龄大于等于26小于30的用户数据信息 */
JSON
{
    "query": {
        "term": {
            "age": {
                "gte": 26,
                "lt": 30
            }
        }
    }
}


/* exists查询 - 用于查找文档中是否包含指定字段/没有某个字段,类似SQL的is null */
请求形式 POST
URL: http://{ELK服务地址}:9200/{索引名称}/{类型}/_search
/* 例如:查询包含title字段的数据 */
JSON
{
    "query": {
        "exists": {
            "field":"title"
        }
    }
}


/* match查询 - 全文本查询(模糊)以及精确查询都可以用 */
请求形式 POST
URL: http://{ELK服务地址}:9200/{索引名称}/{类型}/_search
/* 例如:查询名字中带“云”字的数据信息 */
JSON
{
    "query": {
        "match": {
            "name": "云"
        }
    }
}

/* bool查询 - 合并多个条件的查询结果的布尔逻辑 */
请求形式 POST
操作符:
    must:多个查询条件完全匹配,AND
    must_not:多个查询条件的相反匹配,NOT
    should:至少有一个查询条件匹配,OR
URL: http://{ELK服务地址}:9200/{索引名称}/{类型}/_search
/* 例如:查询用户性别为男的且年龄不大于30岁的数据 */
JSON
{
    "query": {
        "bool": {
            "must": {
                "match": {
                    "sex": "男"
                }
            },
            "must_not": {
                "range": {
                    "age": {
                        "gt": 30
                    }
                }
             }
        }
    }
}


/* filter查询 - 其他查询都需要计算查询结果的匹配程度,即元数据_source */
/* 过滤查询不考虑_source,且可以缓存查询结果,提升速度 */
请求形式 POST
URL: http://{ELK服务地址}:9200/{索引名称}/{类型}/_search
/* 例如:查询年龄为26岁的用户数据 */
JSON
{
    "query": {
        "bool": {
            "filter": {
                "term": {
                    "age": 26
                }
            }
        }
    }
}
8. IK Analyse
请求形式 POST
URL: http://{ELK服务地址}:9200/_analyze

/* 英文分词 */
JSON
{
    "analyzer": "standard",  // 默认英文分词器
    "text": "hello world"    // 分词文本
}

/* 中文分词 */
JSON
{
    "analyzer": "ik_max_word",  //ik中文分词器名称为ik_max_word
    "text": "你好,中国"          // 分词文本
}
9. 全文检索
请求形式 POST
URL: http://{ELK服务地址}:9200/{索引名称}/_search

/* 单词查询 */
JSON
{
    // hobby这个field匹配 篮球 这个单词
    "query": {
        "match": {
            "hobby": "篮球"
        }
    },
    // 结果高亮
    "highlight": {
        "fields": {
            "hobby": {}
        }
    }
}

/* 多词查询 - 匹配多个单词 */
JSON
{
    // hobby这个field匹配 篮球 足球 这两个单词
    "query": {
        "match": {
            "hobby": "篮球 足球"
        }
    },
    // 结果高亮
    "highlight": {
        "fields": {
            "hobby": {}
        }
    }
}

/* 多词查询 - 同时匹配多个单词 */
JSON
{
    // hobby这个field同时匹配 篮球和足球 这两个单词
    "query": {
        "match": {
            "hobby": {
                "query": "篮球 足球",
                "operator":"and" // AND OR两种情况
            }
        }
    },
    // 结果高亮
    "highlight": {
        "fields": {
            "hobby": {}
        }
    }
}


/* 多词查询 - 设置匹配度40%进行查询 */
JSON
{
    // hobby这个field同时匹配 篮球和足球 这两个单词
    "query": {
        "match": {
            "hobby": {
                "query": "篮球 足球",
                "minimum_should_match":"40%" // 设置匹配度,_source分数越高匹配度越大
            }
        }
    },
    // 结果高亮
    "highlight": {
        "fields": {
            "hobby": {}
        }
    }
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值