Elasticsearch使用教程 Elasticsearch使用说明和总结

前言

对大量数据的存储,检索和分析是现在开发中不可避免的,但以往使用SQL数据库存储、检索数据,显然已无法支持现在动辄千万上亿的海量数据,大量数据写入数据库导致数据写入慢和查询检索更慢,无疑是现在大数据存储和分析的痛点和亟需解决的问题,故需要引入专业引擎Elasticsearch来存储、搜索和分析数据,解决海量数据存储和搜索的问题

一、Elasticsearch简介

Elasticsearch 是一个分布式、高扩展、高实时的RESTful 风格的搜索与数据分析引擎。它能很方便的使大量数据具有搜索、分析和探索的能力。充分利用Elasticsearch的水平伸缩性,能使数据在生产环境变得更有价值。Elasticsearch 的实现原理主要分为以下几个步骤,首先用户将数据提交到Elasticsearch 数据库中,再通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据,当用户搜索数据时候,再根据权重将结果排名,打分,再将返回结果呈现给用户。

二、Elasticsearch概念和术语介绍

1、文档

  • 文档为ES(Elasticsearch简称,后文续用)存储数据的基础单元,一条数据就是一个文档;
  • 对比SQL数据库概念,可以理解文档为表中的一行数据为一个文档;
  • ES的文档为单数或多数实体或对象可以被序列化为包含键值对的 JSON 对象;

示例:

{
    "name":         "John Smith",
    "age":          42,
    "confirmed":    true,
    "join_date":    "2014-06-01",
    "home": {
        "lat":      51.5,
        "lon":      0.1
    },
    "accounts": [
        {
            "type": "facebook",
            "id":   "johnsmith"
        },
        {
            "type": "twitter",
            "id":   "johnsmith"
        }
    ]
}

2、索引

  • 索引为文档集合,一个索引应该是因共同的特性被分组到一起的文档集合,例如存储同一天的日志文档在索引“log-2020.08.16”或存储所有的产品在索引"products"中;
  • 对比SQL数据库概念,可以理解索引为一张表;

3、文档元数据

一个文档不仅仅包含它的数据,也包含元数据有关文档的信息。三个必须的元数据元素如下:

  • _index 文档在哪存放
  • _type 文档表示的对象类别
  • _id 文档唯一标识

_index为文档所在的索引,_type为文档类型用于同索引下不同类别文档的区分,_id 是一个字符串,为文档标识
通过以上三个元数据元素可以准确的找到其标记的文档

4、elasticsearch URL的基本格式

http://localhost:9200/<index>/<type>/[<id>]

其中index、type是必须提供的。id是可选的,不提供es会自动生成。这个三个即上述文档元数据,可准确的定位到某个文档

注: 在url后面加"?pretty",会让返回结果以工整的方式展示出来,适用所有操作数据类的url。"?"表示引出条件,"pretty"是条件内容。

采用http的不同动作,来区分不同操作:

  • GET: 获取资源
  • POST:创建或更新资源
  • PUT: 创建或更新资源
  • DELETE:删除资源

以下示例均不在写ip和端口,请在实际使用中添加

三、Elasticsearch索引管理

1、创建索引

索引在创建文档时可自动创建,自动创建的索引采用的是默认的配置,当然我们也可以手动创建索引,并且设置我们想要的配置(例如设置主分片数量、分析器和映射等等),手动创建方式为:

PUT /zhang-local-2020.08.26
{
    "settings": { ... any settings ... },
    "mappings": {
        "type_one": { ... any mappings ... },
        "type_two": { ... any mappings ... },
        ...
    }
}

2、删除索引

删除索引可删除单个、多个、全部,方式分别为:
删除单个索引:

DELETE /zhang-local-2020.08.26

删除多个索引:

DELETE /zhang-local-2020.08.26,zhang-local-2020.08.25
或
DELETE /zhang-local-*

删除全部索引:

DELETE /_all
或
DELETE /*

四、Elasticsearch数据文档的增删改

1、创建新文档

向zhang-local-2020.08.26索引中添加一条日志记录

POST /zhang-local-2020.08.26/doc/
{
	"endTime": "2020-07-10 17:02:21",
	"requestIp": "127.0.0.1",
	"receiveHost": "127.0.0.1:7002",
	"startTime": "2020-07-10 17:02:21",
	"crtDate": "2020-07-10 17:02:21",
	"capAddress": "",
	"msgId": "202007101702215395068",
	"serviceCode": "openRest_open_POST"
}

此处URL中没有写id,交由ES自动生成,也可自己的指定例如:

PUT /zhang-local-2020.08.26/doc/123
{
	"endTime": "2020-07-10 17:02:21",
	"requestIp": "127.0.0.1",
	"receiveHost": "127.0.0.1:7002",
	"startTime": "2020-07-10 17:02:21",
	"crtDate": "2020-07-10 17:02:21",
	"capAddress": "",
	"msgId": "202007101702215395068",
	"serviceCode": "openRest_open_POST"
}

说明:只有当确定id时,才能使用PUT,否者会报错

2、删除文档

DELETE  /zhang-local-2020.08.26/doc/123

由index、type、id准确定位文档然后删除

3、更新文档

更新可以直接覆盖,直接拿新日志覆盖原来的id为123的日志,例如:

PUT /zhang-local-2020.08.26/doc/123
{
	"endTime": "2020-07-10 17:02:21",
	"requestIp": "127.0.0.1",
	"receiveHost": "127.0.0.1:7002",
	"startTime": "2020-07-10 17:02:21",
	"crtDate": "2020-07-10 17:02:21",
	"capAddress": "123",
	"msgId": "202007101702215395068",
	"serviceCode": "openRest_open_POST"
}

也可以单个字段更新,例如:

POST /zhang-local-2020.08.26/doc/123/_update
{
  "doc": {
     "requestIp": "127.0.0.2"
  }
}

注意:URL后要多加/_update,要更新的字段放在“doc”节点下

五、Elasticsearch数据文档查询

1、单个文档查询

GET /zhang-local-2020.08.26/doc/123

2、多条件检索

2.1、精确查找和匹配

精确查找和匹配(term、terms和match、match_all、match_phrase)
term和match的区别是在开启分词器的前提下,若没有开启分词器(插入文档进行分词和查询语句分词),二者使用上在使用时未见差异,均为关键词查找

下面设置字段分词器的方式:

PUT zhang-local-2020.08.27
{
  "mappings": {
    "doc": {
      "properties": {
        "title":{
          "type": "text",
          "analyzer": "whitespace",
          "search_analyzer": "whitespace"
        }
      }
    }
  }
}

对文档中的title字段开启空格分词器(standard),analyzer为文档分词设置,search_analyzer为查询分词设置

term和match的区别:

  • term是精确查询,直接对关键词进行查找
  • match是模糊查询,对查找的关键词进行分词,然后按分词匹配查找

 我们先放一些数据:

POST /zhang-local-2020.08.27/doc/124
{
    "title": "张鹏",
    "content": "people very love China"
}
POST /zhang-local-2020.08.27/doc/125
{
    "title": "张 鹏",
    "content": "people very love China"
}
POST /zhang-local-2020.08.27/doc/126
{
    "title": "张 三",
    "content": "people very love FuYang"
}
POST /zhang-local-2020.08.27/doc/128
{
    "title": "王 鹏",
    "content": "people very love JieShou"
}

这里我们开启的是title字段的空格分词器,即当有空格时会被分词,那么当我们写入上诉文档时,实际在ES中存储了"张鹏"、“张”、“鹏”、“三”、“王” 这几个关键词,“张 鹏”、“张 三”、"王 鹏"都会被分词

下面我们用term和match分别查找"张鹏",示例:

GET /zhang-local-2020.08.27/doc/_search
{
  "query": {
    "term": {
      "title": "张鹏"
    }
  }
}
结果:
{
  "hits": {
    "total": 1,
    "max_score": 1.0925692,
    "hits": [
      {
        "_index": "zhang-local-2020.08.27",
        "_type": "doc",
        "_id": "124",
        "_score": 1.0925692,
        "_source": {
          "title": "张鹏",
          "content": "people very love China"
        }
      }
    ]
  }
}

GET /zhang-local-2020.08.27/doc/_search
{
  "query": {
    "match": {
      "title": "张鹏"
    }
  }
}
结果:
{
  "hits": {
    "total": 1,
    "max_score": 1.0925692,
    "hits": [
      {
        "_index": "zhang-local-2020.08.27",
        "_type": "doc",
        "_id": "124",
        "_score": 1.0925692,
        "_source": {
          "title": "张鹏",
          "content": "people very love China"
        }
      }
    ]
  }
}

结果是相同的,二者没有区别,因为这里"张鹏"是个完整的词(无空格),分词不分词都一样,只能找到id为124这条文档;

接着我们用term和match分别查找"张 鹏",示例:

GET /zhang-local-2020.08.27/doc/_search
{
  "query": {
    "term": {
      "title": "张 鹏"
    }
  }
}
结果:
{
  "hits": {
    "total": 0,
    "max_score": null,
    "hits": []
  }
}

GET /zhang-local-2020.08.27/doc/_search
{
  "query": {
    "match": {
      "title": "张 鹏"
    }
  }
}
结果:
{
  "hits": {
    "total": 3,
    "max_score": 1.3411059,
    "hits": [
      {
        "_index": "zhang-local-2020.08.27",
        "_type": "doc",
        "_id": "125",
        "_score": 1.3411059,
        "_source": {
          "title": "张 鹏",
          "content": "people very love China"
        }
      },
      {
        "_index": "zhang-local-2020.08.27",
        "_type": "doc",
        "_id": "127",
        "_score": 0.43445712,
        "_source": {
          "title": "王 鹏",
          "content": "people very love JieShou"
        }
      },
      {
        "_index": "zhang-local-2020.08.27",
        "_type": "doc",
        "_id": "126",
        "_score": 0.2876821,
        "_source": {
          "title": "张 三",
          "content": "people very love FuYang"
        }
      }
    ]
  }
}

这里就看出二者区别:

  1. 用term查找"张 鹏",查找结果为空,因为term为精确查询,直接对关键词进行查找,所以直接用"张 鹏"关键词去查询,在文档写入时分词后最终得到的关键词分别为"张鹏"、“张”、“鹏”、“三”、“王”,显然没有匹配的,故结果为空;
  2. 用match查找"张 鹏",得到了3条结果,因为match对查找的关键词进行分词,然后按分词匹配查找,这里"张 鹏"分词为"张"、“鹏”,那么用"张"匹配得到125-“张 鹏”,126-“张 三”,用"鹏"匹配得到125-“张 鹏”,127-“王 鹏”,合并结果集,故得到3条文档;

term和terms的区别:

  • term为单关键词查询,一次只能查询一个关键词
  • terms为多关键词查询,一次可查询多个关键词

 示例:

GET /zhang-local-2020.08.27/doc/_search
{
  "query": {
    "term": {
      "title": "张鹏"
    }
  }
}
结果:
{
  "hits": {
    "total": 1,
    "max_score": 1.1727304,
    "hits": [
      {
        "_index": "zhang-local-2020.08.27",
        "_type": "doc",
        "_id": "124",
        "_score": 1.1727304,
        "_source": {
          "title": "张鹏",
          "content": "people very love China"
        }
      }
    ]
  }
}

GET /zhang-local-2020.08.27/doc/_search
{
  "query": {
    "terms": {
      "title": ["张鹏","王"]
    }
  }
}
结果:
{
  "hits": {
    "total": 2,
    "max_score": 1,
    "hits": [
      {
        "_index": "zhang-local-2020.08.27",
        "_type": "doc",
        "_id": "124",
        "_score": 1,
        "_source": {
          "title": "张鹏",
          "content": "people very love China"
        }
      },
      {
        "_index": "zhang-local-2020.08.27",
        "_type": "doc",
        "_id": "127",
        "_score": 1,
        "_source": {
          "title": "王 鹏",
          "content": "people very love JieShou"
        }
      }
    ]
  }
}

match_all:
查询所有文档,示例:

GET /zhang-local-2020.08.27/doc/_search
{
  "query": {
    "match_all": {}
  }
}

会得到所有文档,返回报文就不放了,太长了

match_phrase:

  • match_phrase 称为短语搜索,要求所有的分词必须同时出现在文档中,同时位置必须紧邻一致
  • match只要其中一个关键词能匹配上就行,不考虑关键词间的联系,故上述查找"张 鹏"连带着把带"张"关键词和带"鹏"关键词的记录一并查出来,这显然不是所有情况都需要的

现在只想查询"张 鹏"的文档,这里就可以用match_phrase,示例:

GET /zhang-local-2020.08.27/doc/_search
{
  "query": {
    "match_phrase": {
      "title": "张 鹏"
    }
  }
}
结果:
{
    "total": 1,
    "max_score": 1.3411059,
    "hits": [
      {
        "_index": "zhang-local-2020.08.27",
        "_type": "doc",
        "_id": "125",
        "_score": 1.3411059,
        "_source": {
          "title": "张 鹏",
          "content": "people very love China"
        }
      }
    ]
}

2.2、bool组合过滤器

  • must、should、must_not过滤器介绍

  must
  所有的语句都 必须(must) 匹配,与 AND 等价。

  must_not
  所有的语句都 不能(must not) 匹配,与 NOT 等价。

  should
  至少有一个语句要匹配,与 OR 等价。

  • bool过滤器

 bool (布尔)过滤器。 这是个 复合过滤器(compound filter) ,它可以接受多个其他过滤器作为参数(包括它自己都可以),并将这些过滤器结合成各式各样的布尔(逻辑)组合
bool过滤器组成部分示例:

{
   "bool" : {
      "must" :     [],
      "should" :   [],
      "must_not" : []
   }
}

每个过滤器都是可选的,但只能存在一个同类型过滤器(例如:bool下只能有一个must过滤器)

下面我们对比SQL举例说明过滤器的使用:

SQL:
SELECT *
FROM   user
WHERE  (age = 20 OR userId = '1')
  AND  name != 'zhang'
  AND  sex = 'man' 
  
ES:
{
	"query": {
		"bool": {
			"should" : [
				{ "term" : {"age" : 20}}, 
				{ "term" : {"userId" : "1"}} 
			],
			"must_not" : {
				"term" : {"name" : "zhang"} 
			},
			"must" : {
				"term" : {"sex" : "man"} 
			}
		}
	}
}
  • bool过滤器嵌套

尽管 bool 是一个复合的过滤器,可以接受多个子过滤器,需要注意的是 bool 过滤器本身仍然还只是一个过滤器。 这意味着我们可以将一个 bool 过滤器置于其他 bool 过滤器内部,这为我们提供了对任意复杂布尔逻辑进行处理的能力。即bool过滤器可以嵌套一层或多层使用。
SQL对比示例:

SQL:
SELECT *
FROM   user
WHERE  (age = 20 OR (age = 40 AND userId = '1'))
  AND  name != 'zhang' 
  AND  sex = 'man' 
  
ES:
{
	"query": {
		"bool": {
			"should" : [
				{ "term" : {"age" : 20}}, 
				{ "bool" : {
						"must": [
							{"term": {"age": 40}},
							{"term": {"userId": "1"}}
						]
					}
				} 
			],
			"must_not" : {
				"term" : {"name" : "zhang"} 
			},
			"must" : {
				"term" : {"sex" : "man"} 
			}
		}
	}
}

2.3、filter过滤器

个人拙见filter过滤器一般用于数值,日期的过滤,可对单值,多值,范围过滤

  • 过滤单值
GET /zhang-local-2020.08.27/doc/_search
{
	"query": {
		"bool": {
			"filter" : {
                "term" : {
                    "age" : 20
                }
            }
		}
	}
}
  • 过滤多值
GET /zhang-local-2020.08.27/doc/_search
{
	"query": {
		"bool": {
			"filter" : {
                "terms" : {
                    "age" : [20, 30]
                }
            }
		}
	}
}

和单值过滤的基本相同,只是term换成了terms,单个数值换成了数组

  • 过滤范围

filter过滤器用的最多的就是范围过滤,上诉的单值和多值都可用must来代替的,范围使用range查询,并提供包含和不包含这两种范围表达式,表达式如下:

gt: > 大于
lt: < 小于
gte: >= 大于或等于
lte: <= 小于或等于

数值范围过滤示例:

GET /zhang-local-2020.08.27/doc/_search
{
	"query": {
		"bool": {
			"filter" : {
                "range": {
                    "age": {
                        "gte": 10,
                        "lte": 20
                    }
                }
		}
	}
}

上诉示例查找"age" 大于等于10,小于等于20的数据
也可单个使用,即只使用"gte",大于等10

日期范围过滤示例:

GET /zhang-local-2020.08.27/doc/_search
{
	"query": {
		"bool": {
			"filter" : {
                "range": {
                    "timestamp": {
                        "gt": "2020-01-01 00:00:00",
                        "lt": "2020-10-01 00:00:00"
                    }
                }
		}
	}
}

range 查询支持对 日期计算(date math) 进行操作,比方说,如果我们想查找时间戳在过去一小时内的所有文档:

"range" : {
    "timestamp" : {
        "gt" : "now-1h"
    }
}

日期计算还可以被应用到某个具体的时间,并非只能是一个像 now 这样的占位符。只要在某个日期后加上一个双管符号 (||) 并紧跟一个日期数学表达式就能做到:

"range" : {
    "timestamp" : {
        "gt" : "2014-01-01 00:00:00",
        "lt" : "2014-01-01 00:00:00||+1M" 
    }
}

早于 2014 年 1 月 1 日加 1 月(2014 年 2 月 1 日 零时)

支持数学表达式(+、-、/):

表达式含义
+1h加1小时
-1d减1天
/d四舍五入到最近的一天

支持数学表达式的时间单位:

单位含义单位含义
yM
w星期d
h小时H小时
m分钟s
  • filter和其他过滤器组合

上面介绍了 must、should、must_not过滤器,filter过滤器可以和他们一起组合使用

{
	"query": {
		"bool": {
			"should" : [],
			"must_not" : [],
			"must" :[],
			"filter" : {
                "range": {}
            }
		}
	}
}

2.4、查询分页和排序

  • 分页

Elasticsearch 接受 from 和 size 参数:
 size
  显示应该返回的结果数量,默认是 10
 from
  显示应该跳过的初始结果数量,默认是 0

可在请求报文中设置分页信息,如获取第10条后20条数据

{
	"query": {
		"bool": {
			"should" : [],
			"must_not" : [],
			"must" :[],
			"filter" : {
                "range": {}
            }
		}
	},
	"size": 10,
	"from": 20
}
  • 排序

sort参数排序设置,后面跟排序字段,order中设置排序方式(正序asc、倒序desc)

{
    "query" : {
        "bool" : {
            "filter" : { "term" : { "user_id" : 1 }}
        }
    },
    "sort": { "date": { "order": "desc" }}
}

3、聚合检索

3.1、聚合概念

类似于 DSL 查询表达式,聚合也有 可组合的语法:独立单元的功能可以被混合起来提供你需要的自定义行为。这意味着只需要学习很少的基本概念,就可以得到几乎无尽的组合。

要掌握聚合,你只需要明白两个主要的概念:

桶(Buckets)
  满足特定条件的文档的集合

指标(Metrics)
  对桶内的文档进行统计计算

每个聚合都是一个或者多个桶和零个或者多个指标的组合。翻译成粗略的SQL语句来解释吧:

SELECT COUNT(color) 
FROM table
GROUP BY color

COUNT(color) 相当于指标。
GROUP BY color 相当于桶。

桶在概念上类似于 SQL 的分组(GROUP BY),而指标则类似于 COUNT() 、 SUM() 、 MAX() 等统计方法。

3.2、简单聚合

首先我们先来个简单的聚合,汽车经销商可能会想知道哪个颜色的汽车销量最好,用聚合可以轻易得到结果,用 terms 桶操作:

GET /cars/transactions/_search
{
    "size" : 0,
    "aggs" : { 
        "popular_colors" : { 
            "terms" : { 
              "field" : "color"
            }
        }
    }
}
  1. 聚合操作被置于顶层参数 aggs 之下(如果你愿意,完整形式 aggregations 同样有效)。
  2. 然后,可以为聚合指定一个我们想要名称,本例中是: popular_colors 。
  3. 最后,定义单个桶的类型 terms 。

上诉聚合返回全部的结果,当我们只想要数量TOP5时,可以这样请求:

GET /cars/transactions/_search
{
    "size" : 0,
    "aggs" : { 
        "popular_colors" : { 
            "terms" : { 
              "field" : "color",
              "size": 5,
              "order": {
                "_count": "asc"
              }
            }
        }
    }
}
  • size指定返回多少个分组
  • order排序方式

terms为桶聚合,相当于MySQL的group by操作,在桶聚合的过程中还可以进行指标聚合,相当于mysql做group by之后,再做各种max、min、avg、sum、stats,详细示例详见下文“嵌套聚合”章节

桶聚合类型:terms、filter、filters、range、date_range、date_histogram、histogram

指标聚合类型:max、min、avg、sum、stats

3.3、过滤和聚合组合

聚合可以在过滤数据后进行,即对数据进行过滤检索后,再进行聚合,示例如下:

{
	"query": {
		"bool": {
			"should" : [...],
			"must_not" : [...],
			"must" :[...],
			"filter" : {
                "range": {
                    "price": {
                        "gte": 10000
                    }
                }
            }
		}
	},
	"size" : 0,
	"aggs" : { 
        "popular_colors" : { 
            "terms" : { 
              "field" : "color"
            }
        }
    }
}

注意当不需要过滤检索的数据(即返回报文中的hits数据),建议将size设置为0

3.4、嵌套聚合

实际使用中,一个聚合往往不能满足我们的需求,这时就需要多个嵌套组合使用,例如,每种颜色汽车的平均价格是多少

为了获取更多信息,我们需要告诉 Elasticsearch 使用哪个字段,计算何种度量。 这需要将度量 嵌套 在桶内, 度量会基于桶内的文档计算统计结果。

让我们继续为汽车的例子加入 average 平均度量:

GET /cars/transactions/_search
{
   "size" : 0,
   "aggs": {
      "colors": {
         "terms": {
            "field": "color"
         },
         "aggs": { 
            "avg_price": { 
               "avg": {
                  "field": "price" 
               }
            }
         }
      }
   }
}
  1. 为度量新增 aggs 层。
  2. 为度量指定名字: avg_price 。
  3. 最后,为 price 字段定义 avg 度量

3.5、条形图聚合

聚合还有一个特性就是能够十分容易地将它们转换成图表和图形。

直方图 histogram 特别有用。 它本质上是一个条形图。 创建直方图需要指定一个区间,如果我们要为售价创建一个直方图,可以将间隔设为 20,000。这样做将会在每个 $20,000 档创建一个新桶,然后文档会被分到对应的桶中。

我们希望知道每个售价区间内汽车的销量。我们还会想知道每个售价区间内汽车所带来的收入,可以通过对每个区间内已售汽车的售价求和得到。

那么可以用 histogram 和一个嵌套的 sum 度量得到我们想要的答案:

GET /cars/transactions/_search
{
   "size" : 0,
   "aggs":{
      "price":{
         "histogram":{ 
            "field": "price",
            "interval": 20000
         },
         "aggs":{
            "revenue": {
               "sum": { 
                 "field" : "price"
               }
             }
         }
      }
   }
}
  • histogram 桶要求两个参数:一个数值字段以及一个定义桶大小间隔。
  • sum 度量嵌套在每个售价区间内,用来显示每个区间内的总收入。

3.6、时间条形图聚合

还有一个功能强大且使用频率最高的条形图统计,date_histogram,时间条形图,它能对时间进行间隔分组,可在 时间 维度上构建指标分析,在实际使用中意义重大

date_histogram 与 通常的 histogram 类似。 但不是在代表数值范围的数值字段上构建 buckets,而是在时间范围上构建 buckets。 因此每一个 bucket 都被定义成一个特定的日期大小 (比如, 1个月 或 2.5 天 )。

构建一个简单的折线图来回答如下问题: 每月销售多少台汽车?

GET /cars/transactions/_search
{
   "size" : 0,
   "aggs": {
      "sales": {
         "date_histogram": {
            "field": "sold",
            "interval": "month", 
            "format": "yyyy-MM-dd" 
         }
      }
   }
}
  • interval,时间间隔要求是日历术语 (如每个 bucket 1 个月)。
  • format,我们提供日期格式以便 buckets 的键值便于阅读。

当然我们也可以在只要指定日期内的分组,例如2020年10月1号9点到21点,某地铁站每小时的人流量

GET /peoples/transactions/_search
{
   "size" : 0,
   "aggs": {
      "sales": {
         "date_histogram": {
            "field": "@timestamp",
            "interval": "1h", 
            "format": "yyyy-MM-dd HH",
            "min_doc_count" : 0,
            "time_zone" : "+08:00",
            "extended_bounds" : {
                  "min" : "2020-10-01 09",
                  "max" : "2020-10-01 21"
              } 
         }
      }
   }
}
  • min_doc_count,这个参数强制返回空 buckets,即默认时间段内没有数据,也会返回一个空 buckets
  • time_zone,时区设置,ES系统默认使用0时区,中国为东八区,需加8小时
  • extended_bounds 数强制返回这个时间段内的结果,其他的都不要

说明:extended_bounds只负责强制分组,无过滤功能,上诉统计中会将21点后的数据全都算在21点上,故要展示某个时间范围的统计数据,需配置bool的过滤一起使用。

六、Elasticsearch日期

1、日期类型

2、时区说明

3、日期格式

七、Elasticsearch常用命令请求

结束语

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值