ElasticSearch:在包含文档的日期范围内查找不同日期的最佳方法是什么?
ElasticSearch: What is the best way to find distinct dates in a daterange that contains documents?
假设我有每月索引,其中包含两个对过滤文档很重要的字段:client_id 和 date_time,以及我对此查询不感兴趣的其他几个数据字段。
如果我想找到在我的索引中存在一段时间的所有不同 date_time(即,如果是订单,将是该期间注册的订单的所有日期,如果是是租来的汽车,就是所有租来的汽车的日子,等等)
假设我想查找 ES 中存在的 2018-10-01 和 2018-10-03 的不同日期时间(此示例的缩写)
我可以从添加布尔查询开始,以将此数据限制在日期范围内:
{
"size" : 0,
"timeout" : 1500,
"query" : {
"bool" : {
"must" : {
"range" : {
"date_time" : {
"from" : "2018-10-01T00:00:00.000Z",
"to" : "2018-10-03T23:59:59.999Z",
"include_lower" : true,
"include_upper" : true
}
}
}
}
}
}
我虽然在代码上按文档计数进行日期范围聚合和过滤:
{
"size" : 0,
"timeout" : 1500,
"query" : {
"bool" : {
"must" : {
"range" : {
"date_time" : {
"from" : "2018-09-19T00:00:00.000Z",
"to" : "2018-10-19T23:59:59.999Z",
"include_lower" : true,
"include_upper" : true
}
}
}
}
},
"aggregations" : {
"date_range_agg" : {
"date_range" : {
"field" : "date_time",
"ranges" : [ {
"from" : "2018-09-30T00:00:00.000Z",
"to" : "2018-10-01T00:00:00.000Z"
}, {
"from" : "2018-10-01T00:00:00.000Z",
"to" : "2018-10-02T00:00:00.000Z"
}, {
"from" : "2018-10-02T00:00:00.000Z",
"to" : "2018-10-03T00:00:00.000Z"
}, {
"from" : "2018-10-03T00:00:00.000Z",
"to" : "2018-10-04T00:00:00.000Z"
}]
}
}
}
}
我可以在我的代码中使用 doc_count > 0 过滤来自 date_range_agg 的桶,但我仍然不喜欢它。
有没有办法在 date_range 存储桶上应用过滤器以仅引入那些包含超过 0 个文档计数的存储桶?
是否有另一种方法可以像 date_time 字段的 agg 那样做一个 "sql group by" 以获得日期范围内 ES 中的所有不同的一个?
总之,我只需要获取给定时间段内实际有文档的所有不同date_time
我们谈论的索引包含 7GB 的文档(每个索引约 160 万个文档),或者 3.8GB 的索引和 200 万个文档。所以我试图找到最有效的方法来检索它。
ADDED-注意:实际上,这个查询用于验证我们所有索引中每天的数据是否存在,其中一些非常小,一些像这样巨大,并且可以时间出来,它们都有一个 dateTime 字段,
并且所有这些都带有对应于第 0 天毫秒和相同时区的时间戳,因此它们不会以毫秒或任何其他方式变化。
在 datetype.keyword 上使用术语聚合的日期范围查询应该 return 唯一日期作为存储桶 ID
我想下面的查询就是您要查找的内容。我已经使用 date histogram and used bucket selector aggregation 实现了 aggregation
的 range part
,因此只有那些具有 document count>0
的范围才会被 returned。
{
"size":0,
"timeout":"1500ms",
"query":{
"bool":{
"must":{
"range":{
"date_time":{
"from":"2018-09-19T00:00:00.000Z",
"to":"2018-10-19T23:59:59.999Z",
"include_lower":true,
"include_upper":true
}
}
}
}
},
"aggregations":{
"date_range_agg":{
"date_histogram":{
"field":"date_time",
"format":"MM-dd-yyyy",
"interval":"week"
},
"aggs":{
"count_bucket_selector":{
"bucket_selector":{
"buckets_path":{
"count":"_count"
},
"script":{
"lang":"expression",
"inline":"count>0"
}
}
}
}
}
}
}
所以上面的查询会 return 为您提供周列表以及该周的文档计数。如果那个星期没有任何文件,它不会显示那个星期。
如果您想分别查看每月或每天的详细信息,您可以在上述查询中使用 month
或 day
而不是 week
。
性能
我建议您尝试使用 profiling 功能,而不是指定 timeout
,以便了解聚合查询需要多长时间才能完成。
下面介绍了如何将分析参数添加到查询中。
{
"profile": true,
"size": 0,
"query": {}
}
添加此内容后,您将能够在回复中查看带有 profile
的单独 JSON 对象。作为响应,您将能够查看每个分片的查询性能的详细信息。特别检查 aggregation
部分,您可以进一步参考此 link 以了解有关时序细分的更多信息。
希望对您有所帮助!
假设我有每月索引,其中包含两个对过滤文档很重要的字段:client_id 和 date_time,以及我对此查询不感兴趣的其他几个数据字段。
如果我想找到在我的索引中存在一段时间的所有不同 date_time(即,如果是订单,将是该期间注册的订单的所有日期,如果是是租来的汽车,就是所有租来的汽车的日子,等等)
假设我想查找 ES 中存在的 2018-10-01 和 2018-10-03 的不同日期时间(此示例的缩写)
我可以从添加布尔查询开始,以将此数据限制在日期范围内:
{
"size" : 0,
"timeout" : 1500,
"query" : {
"bool" : {
"must" : {
"range" : {
"date_time" : {
"from" : "2018-10-01T00:00:00.000Z",
"to" : "2018-10-03T23:59:59.999Z",
"include_lower" : true,
"include_upper" : true
}
}
}
}
}
}
我虽然在代码上按文档计数进行日期范围聚合和过滤:
{
"size" : 0,
"timeout" : 1500,
"query" : {
"bool" : {
"must" : {
"range" : {
"date_time" : {
"from" : "2018-09-19T00:00:00.000Z",
"to" : "2018-10-19T23:59:59.999Z",
"include_lower" : true,
"include_upper" : true
}
}
}
}
},
"aggregations" : {
"date_range_agg" : {
"date_range" : {
"field" : "date_time",
"ranges" : [ {
"from" : "2018-09-30T00:00:00.000Z",
"to" : "2018-10-01T00:00:00.000Z"
}, {
"from" : "2018-10-01T00:00:00.000Z",
"to" : "2018-10-02T00:00:00.000Z"
}, {
"from" : "2018-10-02T00:00:00.000Z",
"to" : "2018-10-03T00:00:00.000Z"
}, {
"from" : "2018-10-03T00:00:00.000Z",
"to" : "2018-10-04T00:00:00.000Z"
}]
}
}
}
}
我可以在我的代码中使用 doc_count > 0 过滤来自 date_range_agg 的桶,但我仍然不喜欢它。
有没有办法在 date_range 存储桶上应用过滤器以仅引入那些包含超过 0 个文档计数的存储桶?
是否有另一种方法可以像 date_time 字段的 agg 那样做一个 "sql group by" 以获得日期范围内 ES 中的所有不同的一个?
总之,我只需要获取给定时间段内实际有文档的所有不同date_time
我们谈论的索引包含 7GB 的文档(每个索引约 160 万个文档),或者 3.8GB 的索引和 200 万个文档。所以我试图找到最有效的方法来检索它。
ADDED-注意:实际上,这个查询用于验证我们所有索引中每天的数据是否存在,其中一些非常小,一些像这样巨大,并且可以时间出来,它们都有一个 dateTime 字段, 并且所有这些都带有对应于第 0 天毫秒和相同时区的时间戳,因此它们不会以毫秒或任何其他方式变化。
在 datetype.keyword 上使用术语聚合的日期范围查询应该 return 唯一日期作为存储桶 ID
我想下面的查询就是您要查找的内容。我已经使用 date histogram and used bucket selector aggregation 实现了 aggregation
的 range part
,因此只有那些具有 document count>0
的范围才会被 returned。
{
"size":0,
"timeout":"1500ms",
"query":{
"bool":{
"must":{
"range":{
"date_time":{
"from":"2018-09-19T00:00:00.000Z",
"to":"2018-10-19T23:59:59.999Z",
"include_lower":true,
"include_upper":true
}
}
}
}
},
"aggregations":{
"date_range_agg":{
"date_histogram":{
"field":"date_time",
"format":"MM-dd-yyyy",
"interval":"week"
},
"aggs":{
"count_bucket_selector":{
"bucket_selector":{
"buckets_path":{
"count":"_count"
},
"script":{
"lang":"expression",
"inline":"count>0"
}
}
}
}
}
}
}
所以上面的查询会 return 为您提供周列表以及该周的文档计数。如果那个星期没有任何文件,它不会显示那个星期。
如果您想分别查看每月或每天的详细信息,您可以在上述查询中使用 month
或 day
而不是 week
。
性能
我建议您尝试使用 profiling 功能,而不是指定 timeout
,以便了解聚合查询需要多长时间才能完成。
下面介绍了如何将分析参数添加到查询中。
{
"profile": true,
"size": 0,
"query": {}
}
添加此内容后,您将能够在回复中查看带有 profile
的单独 JSON 对象。作为响应,您将能够查看每个分片的查询性能的详细信息。特别检查 aggregation
部分,您可以进一步参考此 link 以了解有关时序细分的更多信息。
希望对您有所帮助!