ELK之Elasticsearch常用DSL语句(kibana语句)

2023-11-14

DSL 是什么?

DSL(Domain Specific Language)的缩写,中文翻译为领域特定语言

Wikipedia 对于 DSL 的定义还是比较简单的:

A specialized computer language designed for a specific task.

为了解决某一类任务而专门设计的计算机语言。

与 GPL 相对,DSL 与传统意义上的通用编程语言 C、Python 以及 Haskell 完全不同。通用的计算机编程语言是可以用来编写任意计算机程序的,并且能表达任何的可被计算的逻辑,同时也是 图灵完备 的。

但是在里所说的 DSL 并不是图灵完备的,它们的表达能力有限,只是在特定领域解决特定任务的。

A computer programming language of limited expressiveness focused on a particular domain.

另一个世界级软件开发大师 Martin Fowler 对于领域特定语言的定义在笔者看来就更加具体了,DSL 通过在表达能力上做的妥协换取在某一领域内的高效

而有限的表达能力就成为了 GPL 和 DSL 之间的一条界限。

零、ES基本操作

1、查看索引/mapping

GET /inde_name
GET /[index_name]/_mapping

#例如
GET /online_qd_analysis_202012
GET /online_qd_analysis_202012/_mapping

2、查看集群健康状态

GET /_cat/health
GET /_cat/health?v  #带"?v"就是列出列名的意思

 

3、查询ES中所有的index

GET _cat/indices
GET _cat/indices?v  #带"?v"就是列出列名的意思

4、删除索引

#删除指定索引
DELETE index_name

5、查看索引的分片情况

GET _cat/shards/index_name
GET _cat/shards/index_name?v

如上,每个分片是主副分片、状态、文档数、占用存储、ip等都一目了然。

6、根据docid查询文档

GET /index_name/type_name/docid

#例如
GET /online_qd_analysis_202012/kw/corp_uin_2852156690_2852156690_1442795696_1608777956283

7、常规查找——在Type中所有数据中查找

 注:_search的含义是在所有数据中查找。

#指定index和type;就是在这个type_name中查找的意思
GET index_name/type_name/_search
{
  "size":30,
  "query":{


   }
}

#指定index
GET index_name/_search
{
  "size":30,
  "query":{


   }
}

8、限制查找条数

#限制查找条数有两种方式.1)在get语句中限定 2)在内部参数中限定
#1)GET语句中限定
GET index_name/type_name/_search?size=100
{
  "query": {
        "match": {
            "session_id": 
        }
    }
}

#2)内部参数限定
GET index_name/type_name/_search
{
  "size":3,
  "query": {
        "match": {
            "session_id": 
        }
    }
}

具体规则可以参见:  CSDN

9、ES的基本CURD

下面以一个电商的例子,说明下es的增删改查。

(1)、插入一条数据

 指定docid,POST/PUT都可以;不指定docid,貌似只能POST。

#PUT操作插入一条数据
PUT /my_index/my_type/docid1111
{
    "name":"dior chengyi",
    "desc":"shishang gaodang",
    "price":7000,
    "producer":"dior producer",
    "tags":["shishang","shechi"]
}


#ES7及以后版本有所变更,格式如下。
PUT /my_index/_doc/docid1111
{
    "name":"dior chengyi",
    "desc":"shishang gaodang",
    "price":7000,
    "producer":"dior producer",
    "tags":["shishang","shechi"]
}

注:es7以后格式为"PUT /index_name/_doc/",其中的_doc是必须的标识对文档的操作。


#ES7及以后  不指定docid
PUT /my_index/_doc/
{
    "name":"dior chengyi",
    "desc":"shishang gaodang",
    "price":7000,
    "producer":"dior producer",
    "tags":["shishang","shechi"]
}

注:es7以后格式为"PUT /index_name/_doc/",其中的_doc是必须的标识对文档的操作。

注:es7之后版本都要将type位置换成“_doc”;其实就是ES7将_doc作为默认type了。

(2)、根据docid查询某条记录

#根据docid查询商品
GET /my_index/my_type/docid1111

GET /my_index/_doc/docid1111

(3)、根据其他字段查询记录

GET /my_index/my_type/_search
{
	"size":5,
	"query":{
		"match":{
			"name":"dior chengyi"
		}
	}
}

#es7及之后版本
GET /my_index/_doc/_search
{
	"size":5,
	"query":{
		"match":{
			"name":"dior chengyi"
		}
	}
}

(4)、修改数据

(1)PUT方式修改字段——其他字段依然带上

#把price改成8000.如下是ok的
PUT /my_index/my_type/docid1111
{
	"name":"dior chengyi",
	"desc":"shishang gaodang",
	"price":8000,
	"producer":"dior producer",
	"tags":["shishang","shechi"]
}

(2)PUT方式仅涉及修改字段——其他字段不带上(会覆盖原来所有)

#这样update是不行的.会把docid1111完全覆盖掉
PUT /my_index/my_type/docid1111
{
	"price":9000
}

(3)POST/_update方式修改数据——比较理想的方法

注:先进行查询,查询后存储doc,然后在更新其中的指定的字段的字段值。

#POST方式进行update.注意:"_update"、"doc"等都要有
POST /my_index/my_type/docid1111/_update
{	
	"doc":{
		"price":8500
	}
}

POST /my_index/_doc/docid1111/_update
{	
	"doc":{
		"price":8500
	}
}

5、删除商品数据

#删除商品数据
DELETE /my_index/my_type/docid1111

6、继续插入两条数据

#再插入一条记录
PUT /my_index/my_type/docid1112
{
	"name":"hailanzhijia chenyi",
	"desc":"shangwu xiuxian",
	"price":200,
	"producer":"hailanzhijia producer",
	"tags":["xiuxian"]
}

#在插入一条记录
PUT /my_index/my_type/docid1113
{
	"name":"uniqlo chenyi",
	"desc":"jujia xiuxian",
	"price":150,
	"producer":"uniqlo producer",
	"tags":["jujia","xiuxian"]
}

7、查看所有数据

#查看所有数据
GET /my_index/my_type/_search

GET /my_index/_doc/_search

一、ES高级查询 DSL

0、ES mapping中的数据类型

字符串类型: keyword、text
数字类型: interger long
小数类型: float double
布尔类型: boolean
日期类型: date

①keyword一般用于关键字/词;text存储一段文本。本质区别是text会分词,keyword不会分词;

②所有类型中只有text类型会分词,其余都不分词;

③默认情况ES使用标准分词器。其分词逻辑为:中文单字分词、英文单词分词。


为了便于后续测试创建如下索引
PUT products
{
  "settings":{
    "number_of_shards": 1,
    "number_of_replicas": 0
  },
  "mappings":{
    "properties": {
      "id":{
        "type":"integer"
      },
      "title":{
        "type":"keyword"
      },
      "price":{
        "type":"double"
      },
      "create_at":{
        "type":"date"
      },
      "description":{
        "type":"text"
      }
    }
  }
}

注:discription字段以下形式即为指定分词器
      "description":{
        "type":"text",
        "analyzer": "ik_max_word"
      }


#并插入如下数据

POST /products/_doc/1
{
  "id":1,
  "title":"小浣熊",
  "price":0.5,
  "create_at":"2022-11-11",
  "description":"小浣熊很好吃!!"
}


POST /products/_doc/2
{
  "id":2,
  "title":"唐僧肉",
  "price":1.0,
  "create_at":"2022-11-11",
  "description":"唐僧肉真不错!!很好吃!!"
}

POST /products/_doc/8
{
  "id":8,
  "title":"大辣片",
  "price":1.0,
  "create_at":"2022-11-11",
  "description":"大辣片好好吃!!很好吃!!"
}

POST /products/_doc/
{
  "title":"大鸡腿",
  "price":10,
  "create_at":"2022-11-11",
  "description":"good chicken"
}

POST /products/_doc/
{
  "title":"日本豆",
  "price":1.5,
  "create_at":"2022-11-11",
  "description":"日本豆很好吃!!"
}

POST /products/_doc/
{
  "title":"鱼豆腐",
  "price":3.5,
  "create_at":"2022-11-11",
  "description":"鱼豆腐nice!!很好吃!!"
}


1、语法

#注:ES7之前_doc为实际type,之后为_doc;不过查询的时候_doc可省略。
GET /索引名/_doc/_search 
{
    json格式请求体数据
}

或者省略_doc(建议)
GET /索引名/_search 
{
    json格式请求体数据
}

注:建议查询的时候直接省略_doc,这个时候还会有自动补齐提示。

2、query DSL——查询所有(match_all)

 match_all关键字:返回索引中的全部文档。

GET /products/_search
{
  "query":{
    "match_all": {}
  }
}


注:既然是match_all后面肯定不需要限定任何条件了;但是为了满足json格式所以这里要加个"{}"

3、query DSL——关键词查询(term)

重复三遍:文本匹配不要用term!文本匹配不要用term!文本匹配不要用term!(要用match) 

term关键词:用来使用关键词查询。

①term搜索映射中的keyword类型应当使用全部内容搜索(如“大辣片”);

②text类型默认ES使用标准分词器;其分词逻辑为 对英文单词分词、对中文单字分词。

#keyword搜索完整关键词是能够搜到的
GET /products/_search
{
  "query":{
    "term": {
      "title": "鱼豆腐"
    }
  }
}


注:上述描述json格式的K-V都可以换成如下。
"title":{
  "value":"鱼豆腐"
}


#默认分词器下text搜索完整内容也是搜不到的
GET /products/_search
{
  "query":{
    "term": {
      "description": "日本豆很好吃!!"
    }
  }
}

#默认分词器下text搜索单个汉字是能搜到的
GET /products/_search
{
  "query":{
    "term": {
      "description": "好"
    }
  }
}

#默认分词器下text搜索单个英文单词也是能搜到的
GET /products/_search
{
  "query":{
    "term": {
      "description": "nice"
    }
  }
}

4、query DSL——多关键词查询(terms)

terms关键词:用于某个关键词匹配多个值的查询。和 term 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么文档需要一起去做匹配。


GET /products/_search
{
  "query":{
    "terms": {
      "title": [
        "大鸡腿",
        "大辣片"
      ]
    }
  }
}

5、query DSL——范围查询(range)

range关键字:用来指定查询范围内的文档

#查询加个范围

GET /products/_search
{
  "query":
  {
    "range": {
      "price": {
        "gte": 5,
        "lte": 10
      }
    }
  }
}

6、query DSL——前缀查询(prefix)

prefix关键字:用来检索含有指定前缀的关键词的相关文档

#针对keyword类型是可以前缀查询到的
GET /products/_search
{
  "query":{
    "prefix": {
      "title": {
        "value": "小浣"
      }
    }
  }
}

#针对text类型如果是英文的话也是可以前缀查到的
GET /products/_search
{
  "query":{
    "prefix": {
      "description": {
        "value": "goo"
      }
    }
  }
}

7、query DSL——通配符查询(wildcard)

wildcard关键字:通配符查询。 ?用来匹配一个任意字符  *用来匹配多个任意字符。

 使用标准的shell通配符查询参考: ES官网点击直达

#对于text类型。这样是能查到的
GET /products/_search
{
  "query":{
    "wildcard": {
      "description": {
        "value": "goo?"
      }
    }
  }
}

#这样是查不到的
GET /products/_search
{
  "query":{
    "wildcard": {
      "description": {
        "value": "go?"
      }
    }
  }
}


注:因为good是description字段的一个分词。

8、query DSL——多id查询(ids)

ids关键字:值为数组类型,用来根据一组id获取多个对应的文档。

注:这里相当于指定字段就是docid,感觉用的不是很多了吧。

#注:这里就是限定死查询某些docid的数据,只能是docid。

GET /products/_search
{
  "query": {
    "ids": {
      "values":["1","8"]
    }
  }
}

9、query DSL——模糊查询(fuzzy)

fuzzy关键字:用来模糊查询含有指定关键字的文档。

注意:fuzzy模糊 最大模糊错误必须在0~2之间

①搜索关键词长度为2不允许存在模糊
②搜索关键词长度为3~5允许一次模糊
③搜索关键词长度大于5最大2次模糊

#这样是可以查询到title为“小浣熊”的数据的
GET /products/_search
{
  "query": {
    "fuzzy": {
      "title":"小浣猫"
    }
  }
}

10、query DSL——布尔查询(bool)  重要!!!!!

bool关键字:用来组合多个条件实现复杂查询。相当于逻辑操作,如下。

实际语法为:bool下面套filter/must/should/must_not实现逻辑效果(bool包含四种子句)。
①must:相当于&& 要求同时成立;
②should:相当于|| 一个条件满足即可;
③must_not:相当于! 取非;
④filter: 可以将上述term、range等诸多条件都放在filter里面

must和filter的区别? must和filter是一样的。区别是场景不一样。如果结果需要算分就使用must,否则可以考虑使用filter,使查询更高效。

①must:返回的文档必须满足must子句的条件,并且参与计算分值
②filter:返回的文档必须满足filter子句的条件。但是跟Must不一样的是,不会计算分值, 并且可以使用缓存
 

#must 同时满足条件
GET /products/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term":{"title":"小浣熊"}
        },
        {
          "range": {
            "price": {
              "gte": 10,
              "lte": 20
            }
          }
        }
      ]
    }
  }
}

#should 满足一个条件即可
GET /products/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term":{"title":"小浣熊"}
        },
        {
          "range": {
            "price": {
              "gte": 10,
              "lte": 20
            }
          }
        }
      ]
    }
  }
}

#进一步组合也都是可以的
GET /products/_search
{ 
  "bool": { 
    "filter":[
        {"term":{"key1":value}}
        {"range":{"key2":{"gt":value1,"lt":value2}}}
    ]
    "must":     { "term": { }}, 
    "must_not": { "term": { }}, 
    "should": 
    [ 
      { "term": { }}, 
      { "term": { }} 
    ] 
  } 
}


注:must可以是数组,即[];也可以不是数组,即{}.

11、query DSL——match查询(match)   重要!!!!

match关键字:不仅会显示精确匹配的结果也会显示相似匹配的结果,非常强大。

原理:query可以输入关键词也可以输入一段文本。它会根据你实际查询的字段的类型决定是否对query内容进行分词。①如果你查询的字段是分词的,它就会对你query的内容进行分词然后再去搜。②如果该字段是不分词的就将查询条件作为整体进行查询。

注意文本匹配不要用term而应该用match~~~~

#其本质是拿‘浣’去搜,现在就能匹配到数据;然后再拿‘猫’去搜。
GET /products/_search
{
  "query": {
    "match": {
      "description": "浣猫"
    }
  }
}

#其本质是拿‘浣’去搜,现在就能匹配到数据;然后再拿‘鸡’去搜。显然就匹配到两条数据了。
GET /products/_search
{
  "query": {
    "match": {
      "description": "浣鸡"
    }
  }
}

12、query DSL——multi_match查询(multi_match)   重要!!!!

原理同上,只不过换成了多个字段。

#如下是能搜到数据,本质上是从“description”字段搜到的。
GET /products/_search
{
  "query": {
    "multi_match": {
      "query": "浣猫",
      "fields": ["title","description"]
    }
  }
}


#确实这样去匹配keyword类型的title是不行的
GET /products/_search
{
  "query": {
    "multi_match": {
      "query": "浣猫",
      "fields": ["title"]
    }
  }
}

#description含有‘浣’和‘鸡’的都被搜出来了
GET /products/_search
{
  "query": {
    "multi_match": {
      "query": "浣鸡",
      "fields": ["title","description"]
    }
  }
}

13、query DSL——match_phrase查询(match_phrase)   重要!!!!

match和match_phrase的区别:

match是全文检索,这里的搜索条件是针对查询的字串分词后的所有项;只要发现和搜索条件相关的数据都会出现在结果集中。如果我们不想将我们的查询条件拆分,应该怎么办呢?这个时候就可以使用match_phrase。match_phrase是“短语搜索”,他会将给定的短语(phrase)当成一个完整的查询条件。举个简单的例子,如果你要查询的是“this is”。对于match来说会查询到含有“this”的数据和含有“is”的数据,但是对于match_phrase查到的则是必须含有“this is”的数据。

match_phrase一般用于短语匹配(Phrase Matching)!!

#插入如下三条数据
POST /products/_doc/
{
  "title":"apple",
  "price":"2.2",
  "create_at":"2022-08-12",
  "description":"this is apple"
}


POST /products/_doc/
{
  "title":"orange",
  "price":"2.0",
  "create_at":"2022-08-12",
  "description":"orange is sour"
}

POST /products/_doc/
{
  "title":"banana",
  "price":"1.5",
  "create_at":"2022-08-12",
  "description":"this fruit very delicious"
}
#返回所有包含“this”和“is”的三条数据
GET /products/_search
{
  "query": {
    "match": {
      "description": "this is"
    }
  }
}

#仅返回了包含“this is”的一条数据
GET /products/_search
{
  "query": {
    "match_phrase": {
      "description": "this is"
    }
  }
}



注:match_phrase也可以描述为类型为“phrase”的match
​
"match": {
    "title": {
        "query": "quick brown fox",
        "type":  "phrase"
    }
}

​

举个例子对于匹配了短语"quick brown fox"的文档,意味着同时满足下面三个条件。

①quick、brown和fox必须全部出现在某个字段中。
②brown的位置必须比quick的位置大1。
③fox的位置必须比quick的位置大2。

如果以上的任何一个条件没有被满足,那么文档就不能被匹配。

当然我们可以通过slop参数适当的放松匹配条件。这个后面会提到一点。

14、query DSL——查询是否包含某个字段(exists)

exists 过滤可以用于查找文档中是否包含指定字段或没有某个字段 


#查询包含“id”字段的数据
GET /products/_search
{
  "query": {
    "exists": {"field":"id"}
  }
}

15、指定返回条数(size)

 size关键字:指定查询结果中返回指定条数的数据。注:默认返回10条。

注:size的书写位置没有顺序,最前面、中间、后面都是可以的;符合json规范就成。 

#满足条件的有三条,这里限定只返回2条
GET /products/_search
{
  "query": {
    "match": {
      "description": "this is"
    }
  },
  "size":2
}

16、分页查询(from)

from关键字:用来指定起始返回位置,和size连用可以实现分页效果。

#第一把
GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size":5
}

#翻页第二把
GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "from": 5,
  "size":5
}

17、指定字段排序(sort)

注意:sort和最外层的query平齐!!!! 

GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "price": {
        "order": "desc"
      }
    }
  ]
}

注意:因为排序干扰了ES内部的默认搜索,所以一旦排序后ES的查询结果中就没有score得分了。

18、指定返回字段(_source)

_source关键字:是一个数组,在数组中指定展示哪些字段。

注意:这里的“_source”也是和最外层的“query”平齐的。

GET /products/_search
{
  "query": {
    "match_all": {}
  },
  "_source": ["title","price"]
}

19、更多的查询命令: ES官网点击直达

二、filter查询

准确来说ES中的查询实际上有两种:查询(query)和过滤查询(filter)。查询就是之前提到的query查询,它默认会计算每个返回文档的得分然后还会根据得分进行排序。而filter只会筛选出符合条件的文档不会计算得分,不过它会缓存文档。所以单从性能上来讲,过滤比查询要快。

        换句话说过滤适合在大范围筛选数据,而查询则适合精确匹配数据。一般应用都是首先使用过滤操作过滤数据,然后在过滤后的数据中使用查询匹配数据。显然有了filter后就能大大的降低操作的数据量,使操作更快;在考虑到缓存更是如此。

 语法如下:其实就是bool查询。

GET /products/_search
{ 
  "query":{
	  "bool": { 
	    "filter":[
	        {"term":{"key1":value}}
	        {"range":{"key2":{"gt":value1,"lt":value2}}}
	    ],
	    "must":[
            { "term": { }}
        ],
	    "must_not":[
            { "term": { }}
        ],
	    "should": 
	    [ 
	      { "term": { }}, 
	      { "term": { }} 
	    ] 
	} 
  }
}

注意:在执行filter和query时,ES会先执行filter,后执行query。

注意:filter不一定针对keyword类型,对于text类型也一样可以先通过filter降低目标数据量。总之只要能降低目标数据集的范围就可以了,这才是使用filter的条件。

常见的过滤类型有:term、terms、range、exists、ids等filter。

三、聚合查询(Aggregation aggs)

简单来讲类似于sql中的group by。

注:text类型是不支持聚合的。

为了便于测试创建如下索引
PUT fruit
{
  "mappings": {
    "properties": {
      "title":{
        "type":"keyword"
      },
      "price":{
        "type":"double" 
      },
      "description":{
        "type":"text",
        "analyzer": "ik_max_word"
      }
    }
  }
}


GET fruit

#并插入如下数据

POST fruit/_bulk
{"index":{}}
  {"title":"面包","price":19.9,"description":"小面包很好吃"}
{"index":{}}
  {"title":"大白兔","price":29.9,"description":"大白兔奶糖好吃"}
{"index":{}}
  {"title":"日本豆","price":19.9,"description":"日本豆非常好吃"}
{"index":{}}
  {"title":"旺仔小馒头","price":19.9,"description":"旺仔小曼斗很甜"}
{"index":{}}
  {"title":"大辣片","price":9.9,"description":"大辣片很诱人"}
{"index":{}}
  {"title":"脆司令","price":19.9,"description":"脆司令很管饿"}
{"index":{}}
  {"title":"喜之郎果冻","price":19.9,"description":"小时候的味道"}

1、根据某个字段分组

语法:其语法就是在query平齐的位置加上一个aggs。 

#如下为一个实例。
#其中"shuozhuo_price_group"为此次聚合的结果随便取的一个名字;这个名字是我们自定义的。
#terms也是写死的。其含义是基于那个字段进行分组。
GET /fruit/_search
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "shuozhuo_price_group": {
      "terms": {
        "field": "price"
      }
    }
  }
}


#仅返回结果,不返回原始数据
GET /fruit/_search
{
  "query": {
    "match_all": {}
  },
  "size":0,      #
  "aggs": {
    "shuozhuo_price_group": {
      "terms": {
        "field": "price"
      }
    }
  }
}

返回结果如下:

 整个返回中的aggregations字段就是聚合结果;

buckets是一个数组表示的就是聚合后的数组;

注:如果只想返回聚合结果不想返回查询数据的话,利用size就好了。

2、求最大值/最小值/平均值


#最大值
GET /fruit/_search
{
  "query": {
    "match_all": {}
  },
  "size":0,
  "aggs": {
    "shuozhuo_max_price": {
      "max": {
        "field": "price"
      }
    }
  }
}


#最小值
GET /fruit/_search
{
  "query": {
    "match_all": {}
  },
  "size":0,
  "aggs": {
    "shuozhuo_min_price": {
      "min": {
        "field": "price"
      }
    }
  }
}

#平均值
GET /fruit/_search
{
  "query": {
    "match_all": {}
  },
  "size":0,
  "aggs": {
    "shuozhuo_avg_price": {
      "avg": {
        "field": "price"
      }
    }
  }
}

#求和
GET /fruit/_search
{
  "query": {
    "match_all": {}
  },
  "size":0,
  "aggs": {
    "shuozhuo_sum_price": {
      "sum": {
        "field": "price"
      }
    }
  }
}

关于聚合还有很多其他字段,以如下为例说明每个字段的含义。参考  这里

{
    "size" : 0,
    "query" : { 
        "bool" : {
            "filter" : [
                {"range" : {"time" : {"gte" : 1511924400, "lte" : 1551595501}}},
                {"term" : {"kfuin" : 2852199336}}
            ],
            "must" : {
                "bool" : {
                    "should" : [
                        {"match_phrase" : { "msg.ik" : {"query" : "1", "slop" : 0}}}
                    ],
                    "minimum_should_match" : 1
                }
            }
        }
    },
    "aggs" : {
        "customer_msgnum_aggs" : {
            "terms" : {
                "field": "acc_aggr_field",   #根据acc_aggr_field字段聚合
                "size" : 10,                #指定返回的聚合结果数;默认返回前10个聚合结果。这个顺序是后面order指定的顺序
                "collect_mode" : "breadth_first", 
                "execution_hint": "map" ,
                "order" : {
                    "customer_max_time" : "desc"
                }
            },
            "aggs" : {
                "customer_max_time" : {
                    "max" : {
                        "field" : "time"
                    }
                },
                "customer_msg" : {
                    "top_hits" :{"size" : 1, "_source" : {"includes" : [ "msg", "flow_type", "time", "relation_type", "kfext"]}}
                }
            }
        }
    }
}

(0)query→bool→must→match_phrase。

①query:就是你要查询的短语;

②slop:精确短语(Exact-phrase)匹配也许太过于严格了。也许我们希望含有"quick brown fox"的文档也能够匹配"quick fox"查询,即使位置并不是完全相等的。slop参数就是用来引入一些灵活性的。slop参数告诉match_phrase查询词条能够相隔多远时仍然将文档视为匹配。相隔多远的意思是,你需要移动一个词条多少次来让查询和文档匹配?

(1)query→bool→must→minimum_should_match

表示查询语句在匹配分词的时候,至少应该匹配几个term。这里设为1就能保证查询的语句和命中的数据中至少有一个term是匹配的。注:查询到的数据肯定要和查询字串要有一点相关才行,就是这里保证的了。

(2)customer_msgnum_aggs:为聚合结果自定义的一个名字。

(3)size :指定返回的聚合结果数;默认返回前10个聚合结果,这个顺序是后面order指定的顺序。

(4)collect_mode:通过参数 collect_mode = breadth_first 设置可以将子聚合计算延迟到上层父级被剪切之后再计算。注:这里应该是因为后面嵌套了一个 customer_max_time 子聚合所以才额外指定一下的。

①breadth_first 模式是优先进行广度遍历计算,计算完上层的聚合结果后,再进行每个桶的聚合结果计算;
②depth_first 模式是优先进行深度遍历计算,每个分支进行一次深度遍历计算,然后再进行剪切;
③如果某个字段的 cardinality 大小比请求的 size 大或者这个字段的 cardinality 是未知的,那么默认是 breadth_first,其它默认是 depth_first

(5)Execution hint:提供了两种聚合计算的方式,map 和 global_ordinals。

①global_ordinals 模式。对于海量的数据聚合计算,ES 使用一种 global ordinals 的数据结构来进行 bucket 分配,通过有序的数值来映射每一个 term 字符串实现内存消耗的优化。
②map 模式。直接将查询结果拿到内存里通过 map 来计算,在查询数据集很小的情况下使用 map会加快计算的速度。
        默认情况下只有使用脚本计算聚合的时候才使用 map 模式来计算。即使你设置了 map,ES 也不一定能保证一定使用 map 去做计算,一般情况下不需要关心 Execution hint 设置,ES 会根据场景选择最佳的计算方式

(6)order:就是指定排序。这里指定time字段降序排列。

 一个例子如下:

GET es_XXXXXX_flow_oa_20200623/session/_search?size=100
{
  "size":30,
  "_source":[
    "qq_uin",
    "start_time"
  ],
  "query": {
     #bool过滤:可以用来合并多个多虑天剑查询结果的布尔逻辑
     "bool": {
        #相当于and,里面包括多个term时要中括号
        "must":[
          {
            "term": {
              "session_id": "staff_2854099021_2852996969_2113136800_1592497021783"
            }
          },
          {
            "term":{
               "msg_direction": 1
            }
          },
          #精确匹配文本:用match_phrase替换term即可
          {
            "match_phrase":{
               "CustomerNickname": "uidXXXX4759"
            }
          },
          {
            #允许按照指定范围查找
            "range":{
              "flow_time":{
                  "gt":1592842504,#gt:大于
                  "lt":1592842955 #lt:小于
              }
            }  
          }
        ],
        #相当于not
        "must_not":
        {
          "term":{
            "flow_time":1592842726
          }
        }
     }
  }
}

 如何删除数据:

(1)把GET方法换成POST方法

(2)把 _search 换成 _delete_by_query 。

(3)注意:这东西可能会有延迟,执行删除操作后query语句会完10s左右看到没有这些数据了。

POST es_xxxxx_flow_oa_20210625/session/_delete_by_query
{
  "size":1000,
  "query":{
    "bool":{
      "must":[
        {
          "term":{
            "account_type":0
          }
        },
        {
          "term":{"kfuin":2852199234}
        },
        {
          "range":{
            "flow_time":{
              "gte":1602642490,
              "lte":1642642492
            }
          } 
        }
      ]
    }
  }
}

四、条件更新/删除数据 —— _update_by_query/_delete_by_query

如下所示查询语句能够查询到对应的两条数据。我现在想把其中的kfext字段更新成别的数值。

GET es_qidian_flow_oa_v2_202112/session/_search?routing=2852159342
{
  "query":{
    "bool": {
      "must":[
        {
          "term":{
            "kfuin":2852159342
          }            
        },
        {
          "term":{
            "kfext":321321321
          }
        }
      ]
    }
  }
}

更新语句如下:

POST es_qidian_flow_oa_v2_202112/session/_update_by_query?routing=2852159342
{
  "script": {
      "lang":"painless",
      "source": "ctx._source.kfext=params.kfext",
      "params":{
        "kfext":321321321
      }
  },
  "query":{
    "bool": {
      "must":[
        {
          "term":{
            "kfuin":2852159342
          }            
        },
        {
          "term":{
            "kfext":123123123
          }
        }
      ]
    }
  }
}



注:其中的js语句写成如下也是可以的
  "script": {
      "source": "ctx._source['kfext']=321321321"
  },

注意:_update_by_query关键词不要拼错了,这里拼错了es是不会给出报错的。

注意:更新操作后需要有个生效时间,理论上不超过1min就可以生效。

注意:我们可以单独根据docid来查询每条数据看看这条数据的更新情况,

#根据docid GET一条数据
GET es_qidian_flow_oa_v2_202112/session/AX8fyE9VFSj-ki1XGBzE?routing=2852159342
注:对于上述语句根据es版本的不同可能有的需要加type(我们这里就是session),有的可能有不需要。


#其中的_version就是这条数据的版本号,没改动一次就增加1.

{
  "_index": "es_qidian_flow_oa_v2_202112",
  "_type": "session",
  "_id": "AX8fyE9VFSj-ki1XGBzE",
  "_version": 3,
  "_routing": "2852159342",
  "found": true,
  "_source": {
    "account_type": 2,
    "flow_time": 1640148231,
    "session_id": "",
    "relation_type": 0,
    "kfuin": 2852159342,
    "robotid": 0,
    "account_aggr_field": "2_2852406034",
    "qqpub": 0,
    "flow_type": 2,
    "kfext": 123123123,
    "msg_content": "长时间未收到您的消息",
    "retract_msg": 0,
    "msg_type": 0,
    "msg_direction": 1,
    "account": "2852406034"
  }
}

条件删除语句和上面差不多,如下为一个实例:

POST es_qidian_flow_oa_v2_202112/session/_delete_by_query
{
  "query":{
    "bool": {
      "must":[
        {
          "term":{
            "kfuin":2852159342
          }            
        },
        {
          "term":{
            "kfext":321321321
          }
        }
      ]
    }
  }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ELK之Elasticsearch常用DSL语句(kibana语句) 的相关文章

随机推荐

  • 递归与迭代

    迭代 迭代 迭代简单来讲就是循环 类比于我们循环输出某一个字符数组时的情景 从字符数组中不断取出字符 再将字符输出 迭代的循环过程则是从栈 或者队列 中不断取出要操作的元素 进行操作 与普通循环过程不同的是在不断取出元素的同时也会向栈中放入
  • Java8中Collectors的使用

    前言 基本类型的流没有这个用法 文章目录 averagingDouble averagingInt averagingLong collectingAndThen counting groupingBy groupingByConcurre
  • IRQ和FIQ中断的区别

    FIQ和IRQ是两种不同类型的中断 ARM为了支持这两种不同的中断 提供了对应的叫做FIQ和IRQ处理器模式 ARM有7种处理模式 一般的中断控制器里我们可以配置与控制器相连的某个中断输入是FIQ还是IRQ 所以一个中断是可以指定为FIQ或
  • Mac下如何降级Java、卸载Java

    前言 安装一些组件或插件时 有时会提示错误 What went wrong Could not determine java version from 11 查看组件或插件对应的Java版本会发现 可能只支持 Java 8 但本地安装的Ja
  • 《网络安全》零基础教程-适合小白科普

    网络安全 零基础教程 目录 目录 网络安全 零基础教程 第1章 网络安全基础 什么是网络安全 常见的网络安全威胁 网络安全的三个基本要素 网络安全的保障措施 第2章 网络攻击类型 病毒 蠕虫 木马 后门 DoS DDoS攻击 SQL注入 X
  • Java入门项目——读书管理系统

    Java简单实现读书管理系统 一 前言 二 思路及整体框架 三 代码展示 1 有关读书包 Book 2 有关用户包 3 有关操作书的包 一 前言 相信有很多小伙伴学习完了 JavaSE 基础语法 想知道自己到底学的怎么样 或则学完不知道这么
  • 使用RT-Thread studio 把LVGL移植到RT-Thread 上

    使用RT Thread studio 移植 LVGL到RT Thread中 其实RT Thread 移植LVGL 官方已经出来很多教程 但是但是他出的教程都是基于一些他们适配的BSP 但是其他不适配的怎么办呢 当然是手搓了 前期准备 1 在
  • 深入理解Golang之Map

    目录 写在前面 哈希表 如何解决哈希冲突的问题 1 链表地址法 2 开放地址法 开放地址 线性探测法 开放地址 平方探测法 开放地址 双哈希 Go Map实现 map数据结构 map的结构体为hmap bmap结构体 map的桶 Map扩容
  • 【使用JMeter 对Web服务器压力测试】

    自己使用JMeter测试百度心得 主要用到了 1 添加线程组 一个测试的线程容器 可设置线程个数 循环次数 所有线程启动一次的周期时间 2 在线程组 中添加sample gt http request 一个请求的范式 可以设置请求的url和
  • 关于单个模型切片

    这几天鼓捣了模型切片 遇到好多坑 特此记录 1 切片切什么 切的是模型 模型可以通过Nodevisitor转换为geode 而geode可以分为若干drawable 切的就是这些drawable 因此 要node gt accept vis
  • APP更新机制-静默更新、弱更新、强更新/portal是什么?

    APP更新机制 静默更新 弱更新 强更新 一 静默更新 1 1 功能解释 静默更新就是手机系统悄悄的更新 一般会是用户在应用市场勾选了Wifi状态下 闲时自动更新功能后 手机系统会按它的规则帮用户自动更新APP 这个功能和用户手动去应用市场
  • vue 校验表单报错:model is required for validate to wor

    参考https blog csdn net qq 45376290 article details 107346110 1 属性绑定错误 确保绑定的是 model 而不是v model model 是element ui 里面的一个 属性
  • 压缩感知 热身实验 OMP算法Python实现(详细代码注释)

    压缩感知实验 OMP算法Python实现 一维图信号重建 Experiment Result 一维图信号重建 coding utf 8 Created on Wed Sep 23 21 46 43 2020 author chen impo
  • GetLastError返回值及其含义

    GetLastError返回的值通过在api函数中调用SetLastError或SetLastErrorEx设置 函数并无必要设置上一次错误信息 所以即使一次GetLastError调用返回的是零值 也不能担保函数已成功执行 只有在函数调用
  • dhcp和vrrp技术

    目录 引言 一 DHCP工作原理与配置 1 DHCP 动态主机配置协议 2 DHCP工作原理 3 dhcp配置 同网段 4 dhcp中继 不同同网段 5 例子 二 vrrp作用配置 1 vrrp作用 2 vrrp配置 总结 引言 我们每台电
  • Android系统裁剪:手把手教你如何进行系统裁剪

    内容有点长 想系统裁剪 这篇文章足矣 看完会对系统裁剪及系统有更深的认识 前言 android系统裁剪优化一直是各个厂商定制产品的关键步骤 包括浅层次的去除不必要的apk android apk裁剪定制 和深层次的裁剪整个编译系统和框架层
  • 跨境外贸必看

    Pinterest是一个海外图片社交分享网站 Pinterest与国内小红书的营销方式非常相似 它允许我们定位特定的人群 兴趣甚至位置 借助庞大的用户群体和针对特定受众的能力 它成为外贸与跨境电商的推广营销利器 越来越多的跨境玩家利用它进行
  • 虚拟机opnsense作为dhcp服务器,在OPNsense中,通过主机名或域名访问内部设备

    在局域网环境中 使用域名来访问防火墙或其他设备比使用IP地址更容易让人使用 根据需要 我们可以只使用主机名 服务器 来访问设备上的各种服务 例如文件共享 它比包含域名的名称要短 如果打算运行Web服务器或运行具有Web界面的软件 则可能需要
  • Faster RCNN训练自己的数据集【傻瓜式教程】

    一 下载源码 本文采用的源码是 https github com dBeker Faster RCNN TensorFlow Python3 二 配置环境 由于本文是小白教程 光写几个环境怕有人配置不好或者配置版本搞乱 Faster RCN
  • ELK之Elasticsearch常用DSL语句(kibana语句)

    DSL 是什么 DSL Domain Specific Language 的缩写 中文翻译为领域特定语言 Wikipedia 对于 DSL 的定义还是比较简单的 A specialized computer language designe