0、引言
在业务开发中,我们往往会陷入开发的细枝末节之中,而忽略了事物的本源。
经常有同学问到:
等等等等…..
以上的看似复杂的问题,如果转换成DSL,清楚的写出来,梳理清楚问题的来龙去脉,问题就自然解决了一大半。
所以,请亮出你的dsl,不论什么语言的检索,转换到es查询都是sql查询,在es中对应dsl语法,es再拆解比如:分词match_phrase拆解成各term组合,最终传给lucene处理。
亮出你的dsl,确保编程里的实现和你的kibana或者head插件一致是非常重要、很容易被忽视的工作。
如果对dsl拆解不理解,那就再加上profile:true或者explain:true拆解结果一目了然。
维基百科定义:领域特定语言(英语:domain-specific language、DSL)指的是专注于某个应用程序领域的计算机语言。又译作领域专用语言。
Elasticsearch提供基于JSON的完整查询DSL来定义查询。 将Query DSL视为查询的AST(抽象语法树),由两种类型的子句组成:
1、叶子查询子句
叶查询子句查找特定字段中的特定值,例如匹配,术语或范围查询。 这些查询可以单独使用。
2、复合查询子句
复合查询子句可以组合其他叶子或复合查询,用于以逻辑方式组合多个查询(例如bool或dis_max查询),或更改其行为(例如constant_score查询)。
给个例子,一看就明白。
1GET "localhost:9200/_search
2{
3 "query": {
4 "bool": {
5 "must": [
6 { "match": { "title": "Search" }},
7 { "match": { "content": "Elasticsearch" }}
8 ],
9 "filter": [
10 { "term": { "status": "published" }},
11 { "range": { "publish_date": { "gte": "2015-01-01" }}}
12 ]
13 }
14 }
15}
16
看到这里,可能会有人着急了:“我X,这不是官网定义吗?再写一遍有意思吗?”
引用一句鸡汤话,“再显而易见的道理,在中国,至少有一亿人不知道”。同样的,再显而易见的问题,在Elasticsearch技术社区也会有N多人提问。
基础认知不怕重复,可怕的是对基础的专研、打磨、夯实。
Elasticsearch相关的核心操作,广义上可做如下解读,不一定涵盖全,仅抛砖引玉,说明DSL的重要性。
从大到小。
集群的管理,一般我们会使用Kibana或者第三方工具Head插件、cerebro工具、elastic-hq工具。
基本上硬件的(磁盘、cpu、内存)使用率、集群的健康状态都能一目了然。
但基础的DSL会更便捷,便于细粒度分析问题。 如:集群状态查询:
1GET /_cluster/stats?human&pretty
如:节点热点线程查看:
1GET /_nodes/hot_threads
如:集群分片分配情况查看:
1GET /_cluster/allocation/explain
索引生命周期是一直强调的概念,主要指索引的“生、老、病、死”的全过程链条的管理。
创建索引我们优先使用较单纯index更灵活的template模板。
创建索引类似Mysql的创建表的操作,提前设计好表结构对应ES是提前设计好Mapping非常重要。
两个维度:
1PUT _template/template_1
2{
3 "index_patterns": ["te*", "bar*"],
4 "settings": {
5 "number_of_shards": 1
6 },
7 "mappings": {
8 "_doc": {
9 "_source": {
10 "enabled": false
11 },
12 "properties": {
13 "host_name": {
14 "type": "keyword"
15 }
16 }
17 }
18 }
19}
20'
21
举例:
1POST /my_index/_freeze
2POST /my_index/_unfreeze
如:索引清理缓存。
1POST /twitter/_cache/clear
如:某原因导致分片重新分配,_recovery查看分片分配状态。
1GET index1,index2/_recovery?human
1DELETE my_index
高版本的索引生命周期管理推荐使用:ILM功能。
这个是大家再熟悉不过的了。
单条导入数据、批量bulk写入数据、第三方同步数据(本质也是批量)。 举例:
1POST _bulk
2{ "index" : { "_index" : "test", "_id" : "1" } }
3{ "field1" : "value1" }
删除数据包括:指定id删除 delete和批量删除delete_by_query(满足给定条件)。
更新操作。包括:指定id的update/upsert或者批量更新update_by_query。
这是ES的重头戏。包含但不限于:
1、支持精确匹配查询的:term、range、exists、wildcard、prefix、fuzzy等。
2、支持全文检索的:match、match_phrase、query_string、multi_match等
1、Bucketing分桶聚合 举例:最常用的terms就类似Mysql group by功能。
2、Metric计算聚合 举例:类比Mysql中的: MIN(), MAX(), SUM() 操作。
3、Pipeline针对聚合结果聚合 举例:bucket_script实现类似Mysql的group by 后having的操作。
留给大家结合业务场景思考添加。
讲了那么多,实践中遇到问题咋办? 这里把开头提到的几个问题逐一解答一下。
实际Mysql业务中,我们一般是先验证sql没有问题,再写业务代码。
实际ES业务中,也一样,先DSL确认没有问题,再写业务代码。
写完java或者python后,打印DSL,核对是否完全一致。
不一致的地方基本就是结果和预期不一致的原因所在。
第一步:借助analyzer API分析查询语句和待查询document分词结果。
1GET my_index/_analyze
2{
3 "field": "text",
4 "text": "华为鸿蒙系统发布-可随时替代安卓",
5 "analyzer":"ik_smart"
6}
这个API的重要性,再怎么强调都不为过。
第二步:可以借助profile:true查看细节。第三步:核对match_phrase词序的原理。
6.3版本后已经支持sql,如果不会写,可以借助translate 如下API翻译一下。
不够精确,但足够参考用了,需要根据业务细节微调。
当然,还是建议,从业务出发,自己写DSL。
从大往小,逐步细化排解
本文分享自 铭毅天下Elasticsearch 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!