Elasticsearch 一
Elasticsearch, Kibana, Beats和 Logstash(简称 ELK Stack
概述
- 官网地址: https://www.elastic.co/cn
- Elasticsearch是基于 Lucene搭建的(Lucene是 Apache软件基金会的项目, 它是免费开源的提供全文搜索功能类库的工具包), 实时的存储, 可扩展到上百台服务器, 处理 PB级别的数据, 并使用 java语言开发的
- Elasticsearch应用案例: GitHub, Stack Overflow, 百度, 新浪, 阿里
数据格式
- ES的 Index对应 Mysql的数据库, Types对应表, Documents相当于表的行, 这里 Types的概念已被逐渐弱化, 6.X中一个 Index下已经只能含一个 type, 7.X开始 Type的概念已被删除
索引& 映射& 文档(创建/更新/删除/查询)
# 创建索引(创建数据库)
PUT http://127.0.0.1:9200/user
参数: {
"settings" : {
"number_of_shards" : 3, # 分片个数(索引创建后无法更改
"number_of_replicas" : 1 # 副本个数(可动态更改
}
}
返回: {
"acknowledged": true, # true表示操作成功
"shards_acknowledged": true, # 分片操作成功
"index": "shopping"
}
# 修改该索引的副本数
PUT http://127.0.0.1:9200/user/_settings
{
"settings" : {
"number_of_replicas" : 1 # 副本个数(可动态更改
}
}
* 注: 创建索引库的分片数默认 1片(7.x), 在之前的版本中是默认 5片
* 重复添加相同索引, 则会返回错误信息
# 查询所有索引
GET http://127.0.0.1:9200/_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
yellow open user gSJkmVryTv--UIGwtCkM0w 1 1 0 0 208b 208b
# 查看指定索引
GET http://127.0.0.1:9200/user
{
"shopping": {
"aliases": {},
"mappings": {},
"settings": {
"index": {
"creation_date": "1638243432373", 创建事件
"number_of_shards": "1", 主分片数量
"number_of_replicas": "1", 副分片数量
"uuid": "gSJkmVryTv--UIGwtCkM0w",
"version": {
"created": "7080099"
},
"provided_name": "user"
}
}
}
}
# 删除指定索引
DELETE http://127.0.0.1:9200/user
{
"acknowledged": true
}
# 删除后再查该索引
GET http://127.0.0.1:9200/user
{
"error": {
"root_cause": [
{
"type": "index_not_found_exception",
"reason": "no such index [user]",
"resource.type": "index_or_alias",
"resource.id": "user",
"index_uuid": "_na_",
"index": "user"
}
],
"type": "index_not_found_exception",
"reason": "no such index [user]",
"resource.type": "index_or_alias",
"resource.id": "user",
"index_uuid": "_na_",
"index": "user"
},
"status": 404
}
# 创建映射(类似表结构 如字段名称, 类型, 长度, 约束等)
PUT http://127.0.0.1:9200/user/_mapping
参数: {
"properties": {
"name":{
"type": "text",
"index": true # 是否索引, 默认为 true
},
"age":{
"type": "long",
"index": false
}
}
}
返回: {
"acknowledged": true
}
# 查看映射
GET http://127.0.0.1:9200/user/_mapping
## type类型:
String类型分两种:
- [text可分词, keyword不可分词]
Numerical数值类型分两类:
- 基本数据类型: [long, integer, short, byte, double, float, half_float]
- 浮点数的高精度类型: scaled_float
Date日期类型
Array数组类型
Object对象
## index: 是否索引, 默认为 true
## store: 是否将数据进行独立存储, 默认为 false
- 原始的文本会存储在 _source里面, 默认情况下其他提取出来的字段都不是独立存储的, 而是从 _source里面提取出来的
- 独立存储的字段要比从 _source中解析快得多, 但是也会占用更多的空间
## analyzer: 指定分词器[stop/standard/ik_smart最粗粒度的拆分/ik_max_word文本做最细粒度的拆分]
# 创建文档(指创建表数据)
POST http://127.0.0.1:9200/shopping/_doc
参数: {
"title":"小米",
"category":"手机",
"image":"http://www.abc.com/abc.jpg",
"price":1000.00
}
返回: {
"_index": "shopping",
"_type": "_doc",
"_id": "PRwAb30B83jdkzqUAh66", 未指定id, 则 ES会随机生成主键id
"_version": 1, 版本
"result": "created", 表示创建成功
"_shards": {
"total": 2, 分片总数
"successful": 1, 分片成功数
"failed": 0 分片失败数
},
"_seq_no": 0,
"_primary_term": 1
}
# 创建& 更新文档(当主键 id不存在, 则新建文档, 或存在则更新
# 或创建又可以不指定主键: PUT http://127.0.0.1:9200/shopping
PUT http://127.0.0.1:9200/shopping/_doc/1
参数: ...
返回: {
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_version": 1, 版本
"result": "created", 首次生成时 created, 重复提交时 updated
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 1,
"_primary_term": 1
}
* 注: 以上方式修改需要指定所有字段, 也就是每次修改所有字段(全量)
# 更新文档
POST http://127.0.0.1:9200/shopping/_update/1
参数: {
"doc": {
"price":3000.00 # 指定某一或几个字段
}
}
返回: {
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_version": 3,
"result": "updated",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 7,
"_primary_term": 1
}
# 删除文档(*删除一个文档不会立即从磁盘上移除, 是被标记成已删除
DELETE http://127.0.0.1:9200/shopping/_doc/1
{
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_version": 4,
"result": "deleted", deleted表示数据被标记为删除
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 8,
"_primary_term": 1
}
# 查询文档
GET http://127.0.0.1:9200/shopping/_doc/1
正常存在的文档返回: {
"_index": "shopping", 索引
"_type": "_doc", 文档类型
"_id": "1",
"_version": 2,
"_seq_no": 2,
"_primary_term": 1,
"found": true, true表示找到, false表示未找到
"_source": { 文档源信息
"title": "小米手机",
"category": "小米",
"images": "http://www.gulixueyuan.com/xm.jpg",
"price": 3000
}
}
已删除的文档返回: {
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"found": false
}
不存在的文档返回: {
"_index": "shopping",
"_type": "_doc",
"_id": "22",
"_version": 1,
"result": "not_found", not_found表示未查找到
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 9,
"_primary_term": 1
}
# 条件删除文档
POST http://127.0.0.1:9200/shopping/_delete_by_query
参数: {
"query":{
"match":{
"price":3000.00
}
}
}
返回 1: { 条件内未筛选出数据
"took": 117,
"timed_out": false,
"total": 0,
"deleted": 0,
"batches": 0,
"version_conflicts": 0,
"noops": 0,
"retries": {
"bulk": 0,
"search": 0
},
"throttled_millis": 0,
"requests_per_second": -1,
"throttled_until_millis": 0,
"failures": []
}
返回 2: {
"took": 171, 耗时
"timed_out": false,
"total": 2, 总数
"deleted": 2, 删除两条数据
"batches": 1,
"version_conflicts": 0,
"noops": 0,
"retries": {
"bulk": 0,
"search": 0
},
"throttled_millis": 0,
"requests_per_second": -1,
"throttled_until_millis": 0,
"failures": []
}
高级查询
# 查询所有
GET http://127.0.0.1:9200/student/_search
参数: {
"query": {
"match_all": {}
}
}
返回: {
"took": 4, 查询花费时间(毫秒)
"timed_out": false,
"_shards": { 分片信息
"total": 1, 总数
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": { 搜索命中结果
"total": {
"value": 1, 被命中的文章总数
"relation": "eq" eq表示计数准确, gte表示计数不准确
},
"max_score": 1, 匹配度分值
"hits": [ 命中结果集合
{}
]
}
}
# 匹配查询:
参数: {
"query": {
"match": {"name":"zhangsan"}
}
}
字段匹配查询: 与 match类似, 不同的是, 可以在多个字段中查询
参数: {
"query": {
"multi_match": {
"query": "zhangsan",
"fields": ["name","nickname"]
}
}
}
关键字精确查询: 精确的关键词匹配查询, 不会对查询条件进行分词
参数: {
"query": {
"term": {
"name": {
"value": "zhangsan"
}
}
}
}
多关键字精确查询: 指定多值进行匹配
参数: {
"query": {
"terms": {
"name": ["zhangsan","lisi"]
}
}
}
指定查询字段: 文档默认返回所有字段
参数: {
"_source": ["name","nickname"], 指定要返回的字段
"query": {
"terms": {
"nickname": ["zhangsan"]
}
}
}
过滤字段: [includes来指定想要显示的字段, excludes来指定不想要显示的字段]
参数: {
"_source": {
"includes": ["name","nickname"] 指定要返回的字段
},
"query": {
"terms": {
"nickname": ["zhangsan"]
}
}
}
组合查询: `bool`将多个条件组合: `must`(必须), `must_not`(必须不), `should`(应该)
参数: {
"query": {
"bool": { // 条件
"must": [ // 多个条件 and
{
"match": { // 匹配
"cateId": 100
}
}, // and
{
"match": { // 匹配
"price": 50
}
}
],
"should": [ // 多个条件 or
{
"match": { // 匹配
"cateId": 100
}
}, // or
{
"match": { // 匹配
"cateId": 101
}
}
],
"filter": {
"range": { // 范围查询
"price": {
"gt": 5000 // 价格大于5000的
}
}
}
}
}
}
gt 大于>
gte 大于等于>=
lt 小于<
lte 小于等于<=
# 模糊查询
- fuzzy会在一组搜索词内查询可能的变体
- 通过 fuzziness指定偏差距离. 差几个字符 1就是差一个, 0不差也就是完全匹配
参数: {"query": {"fuzzy": {"title": {"value": "zhangsan"}}}}
参数: {"query": {"fuzzy": {"title": {"value": "红米", "fuzziness": 0}}}}
# 排序
单字段排序
参数: {
"query": {
"match": {
"name":"zhangsan"
}
},
"sort": [{
"age": {
"order":"desc"
}
}]
}
多字段排序: 先按照年龄排序, 然后按照相关性得分排序
参数: {
"query": {
"match_all": {}
},
"sort": [
{
"age": {
"order": "desc"
}
},
{
"_score": {
"order": "desc"
}
}
]
}
# 高亮查询
参数: {
"query": {
"match_phrase": { 完全匹配
"category": "小华"
}
},
"highlight": { 高亮显示(会对指定字段内容自动加html tag)
"fields": { 指定字段
"category": {} 指定了字段 category
}
}
}
参数: {
"query": {
"match": {
"name": "zhangsan"
}
},
"highlight": {
"pre_tags": "<font color='red'>", 前置标签
"post_tags": "</font>", 后置标签
"fields": { 需要高亮的字段
"name": {}
}
}
}
# 分页查询
from: (页码 - 1) * 每页显示条数
size: 10 每页显示的条数
# 聚合查询(对应 Mysql的 Group by或最大值, 最小值, 求和, 去重, 平均值等
参数 1: {
"aggs": { // 聚合操作
"price_group": { // 统计结果的, 名称自定义的
"terms": { // 分组统计
"field": "price" // 指定分组字段
}
}
},
"size": 0 // 这个参数设置0, 则不返回hits原始数据
}
参数 2: {
"aggs": { // 聚合操作
"price_avg": { // 统计结果的, 名称自定义的
"avg": { // 平均值
"field": "price" // 指定分组字段
}
}
},
"size": 0 // 这个参数设置0, 则不返回hits原始数据
}
参数 3: {
"aggs":{
"max_age":{
"max":{"field":"age"}
}
},
"size":0
}
参数 4: {
"aggs":{
"sum_age":{
"sum":{"field":"age"}
}
},
"size":0
}
参数 5: {
"aggs":{
"distinct_age":{
"cardinality":{"field":"age"}
}
},
"size":0
}
State聚合: 一次性返回 count, max, min, avg和 sum五个指标
参数: {
"aggs":{
"stats_age":{
"stats":{"field":"price"}
}
},
"size":0
}
返回: {
"took": 68,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": null,
"hits": []
},
"aggregations": {
"stats_age": {
"count": 1,
"min": 3999,
"max": 3999,
"avg": 3999,
"sum": 3999
}
}
}
如果您觉得有帮助,欢迎点赞哦 ~ 谢谢!!