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
        }
    }
}

如果您觉得有帮助,欢迎点赞哦 ~ 谢谢!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值