elasticsearch
基于反向索引的文档型数据库,主要用于日志查询。
ELK Introduction
Elasticsearch 是一个搜索和分析引擎。Logstash 是服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,然后将数据发送到诸如 Elasticsearch 等“存储库”中。Kibana 则可以让用户在 Elasticsearch 中使用图形和图表对数据进行可视化。
Kibana
查询集群(cluster)情况
# 检查群集运行状况 GET /_cat/health?v # 获得群集中的节点列表 GET /_cat/nodes?v # 列出所有索引 GET /_cat/indices?v # 创建索引并查看 PUT /customer?pretty GET /_cat/indices?v
查询
GET [index<regex>]/_search
部分返回参数:
- timeout 限制查询的返回超时时间
- size 默认 10 ,返回的文档数量
- from 默认 10 ,应该跳过的初始文档数量
理解为什么深度分页是有问题的,我们可以假设在一个有 5 个主分片的索引中搜索。 当我们请求结果的第一页(结果从 1 到 10 ),每一个分片产生前 10 的结果,并且返回给 协调节点 ,协调节点对 50 个结果排序得到全部结果的前 10 个。
现在假设我们请求第 1000 页–结果从 10001 到 10010 。所有都以相同的方式工作除了每个分片不得不产生前10010个结果以外。 然后协调节点对全部 50050 个结果排序最后丢弃掉这些结果中的 50040 个结果。
可以看到,在分布式系统中,对结果排序的成本随分页的深度成指数上升。这就是 web 搜索引擎对任何查询都不要返回超过 1000 个结果的原因。
查询:一个评分的匹配,计算相似度。
过滤:一个不评分的匹配,只有是或否。性能更好。
下面的查询针对tweents类型,并使用以下的条件:
name 字段中包含 mary 或者 john date 值大于 2014-09-10 _all_ 字段包含 aggregations 或者 geo +name:(mary john) +date:>2014-09-10 +(aggregations geo) ?q=%2Bname%3A(mary+john)+%2Bdate%3A%3E2014-09-10+%2B(aggregations+geo)
DSL 查询
- 排序
- asc 升序
- desc 降序
- 类型
- .text 会分词,然后进行索引
- 支持模糊、精确查询
- 不支持聚合
- .keyword 不进行分词,直接索引
- 支持模糊、精确查询
- 支持聚合
- .text 会分词,然后进行索引
标准查询
- match 全文匹配或精确匹配
- match_all 匹配所有
- multi_match 在多个字段上执行相同的 match 查询
单词查询与过滤
- term 查询单值
- terms 查询多值
组合条件查询与过滤
- bool
- must 必须匹配
- should 满足任意语句,将增加相关性得分
- must_not 必须不匹配
- filter 必须匹配,以不评分的过滤模式来进行
范围查询与过滤
- range
- gt >
- gte >=
- lt <
- lte <=
存在和损失过滤器
- filter
- exists
- missing
前匹配查询
- prefix
通配符查询
- wildcard
*
?
最佳字段
dis_max
{ "query": { "dis_max": { "queries": [ { "match": {"title": "Brown fox"}, "match": {"body": "Brown fox"} } ] } } }
若文档的 title 有,而 body 中没有,该文档会得到更高的评分,不用 dis_max 则相反
tie_breaker 提供了一种 dis_max 和 bool 之间的折中选择,评分方式如下:
- 获取最佳匹配语句的评分 _score
- 将其他匹配语句的评分与 tie_breaker 相乘
- 对以上评分求和并规范化
multi_match 有 best_fields, most_fields, cross_fields 最佳字段 (default),多数字段,跨字段等模式
常量评分:onstant_score 将一个不变的常量评分应用于所有匹配的文档,经常被用于只需要执行一个 filter 而没有其他查询的情况,可用来代替只有 filter 语句的 bool 查询。
全文搜索
查询的两个重要方面:相关性和分析
match 的步骤如下:
- 分析字段类型
- 分析查询字符串,得到单词
- 用 term 查询,在倒排索引中查找(多次多次使用 term,合并结果)
- 为文档评分
参数:
{ "query": { "match": { "title": { "query": "abc def", "operator": "and", "minimum_should_match": "75%" } } } }
minimum_should_match 还可以限定 必须 满足 should 的条件数,boost 参数可以提高 should 条件的重要性
match
GET log/_search { "query": { "match": { "key": "abc def" } } }
不一定是完全匹配 abc def
,而是会根据相关性打分,单独的 adc
或 def
也有可能匹配上
match_phrase
结果会匹配完整的 abc def
,也包含 xxx abc def xxx
的情况
match_phrase 和 regexp
regexp 针对的是单个词项;match_phrase 针对多个词项的相对位置
实际上 es 会对查询字符进行分析(切分),之后再进行匹配
highlight
高亮某个字段 (key)
GET log/_search { "query": { "match": { "key": "abc def" } }, "highlight": { "field": { "key": {} } } }
结构化搜索
term 精确值查询:
GET log/_search { "query": { "constant_score": { "filter": { "term": { "key": "value" } } } } }
查看字段是否可以用精确值查询,通过 analyze API,通过结果的 token 等判断:
GET log/_analyze { "field": "key", "text": "value" }
聚合
桶 buckets 满足特定条件的集合
指标 metrics 对桶内文档进行统计计算
例如:
SELECT COUNT(color) FROM table GROUP BY color
COUNT(color) -> 指标 GROUP BY color -> 桶
Example
查询特定兴趣爱好员工平均年龄:
GET employee/_search { "aggs": { "all_interests": { "terms": { "field": "interests" }, "aggs": { "average_age": { "avg": { "field": "age" } } } } } }
统计每种颜色车辆价格的平均值:
GET cars/transactions/_search { "size": 0, "aggs": { "colors": { "terms": { "field": "color" }, "aggs": { "average_price": { "avg": { "field": "price" } } } } } }
统计每种颜色车辆的制造商分部:
GET cars/transactions/_search { "size": 0, "aggs": { "colors": { "terms": { "field": "color" }, "aggs": { "average_price": { "avg": { "field": "price" } }, "make": { "terms": { "field": "make" } } } } } }
统计每种颜色车辆的制造商分布,以及各个制造商生产的汽车的最高价和最低价:
GET cars/transactions/_search { "size": 0, "aggs": { "colors": { "terms": { "field": "color" }, "aggs": { "average_price": { "avg": { "field": "price" } }, "make": { "terms": { "field": "make" }, "aggs": { "min_price": { "min": { "field": "price" } }, "max_price": { "max": { "field": "price" } } } } } } } }
extended_stats 扩展度量,统计的基础上还增加了多种复杂的统计信息;stats 可以统计数量
关键在于区分哪些是桶,哪些是指标,terms 这些字段会划分子桶,而 sum, avg 等是指标,不会产生新桶
Data Histogram 聚合
GET log/_search { "size": 0, "aggs": { "name": { "date_histogram": { "field": "@timestamp", "fixed_interval": "1h", "format": "yyyy-MM-dd hh:mm:ss" } } } }
interval: year, quarter, month, …
其他参数:
- time_zone
- offset
- missing
- min_doc_count
- extended_bounds