挣扎在以下问题上–我在ElasticSearch中有一个巨大的数据集,我想比较两个时间段内不同的ID。
下面是一个简单的例子,这样你就能更好地理解我的意思:以下数据是在过去24小时内发送的。
{id: 1}, {id: 2}, {id: 3}
而这个数据是在一周前的24小时内发送的。
{id: 2}, {id: 3}, {id: 4}
我想输出。
1, 4
有什么想法?
解决方案:
Bucket选择器聚合 可以用来选择在一个区间内出现而在其他区间内不出现的字段。
我取了一个数据集,其中有三份文件,分别有唯一的ID 1和2。id 1出现在 “2020-04-22 “和 “2020-04-23 “这两个日期,而Id 2只出现在 “2020-04-23″。所以查询应该只返回Id 2
数据。
"hits" : [
{
"_index" : "index21",
"_type" : "_doc",
"_id" : "N48Xp3EB1jFeu7E5np_U",
"_score" : 1.0,
"_source" : {
"id" : 1,
"date" : "2020-04-23"
}
},
{
"_index" : "index21",
"_type" : "_doc",
"_id" : "OI8Xp3EB1jFeu7E5z5-5",
"_score" : 1.0,
"_source" : {
"id" : 1,
"date" : "2020-04-22"
}
},
{
"_index" : "index21",
"_type" : "_doc",
"_id" : "OY8Yp3EB1jFeu7E5GJ_V",
"_score" : 1.0,
"_source" : {
"id" : 2,
"date" : "2020-04-23"
}
}
]
使用 术语汇总 获取所有唯一的ID。在每个术语下查找不同区间的文档数。选择其中一个区间内文档数为0的术语。
Terms 1
"2020-04-22" 1(doc count)
"2020-04-23" 1(doc count)
2
"2020-04-22" 0(doc count)
"2020-04-23" 1(doc count)
Select term 2
查询。
{
"size": 0,
"aggs": {
"ids": {
"terms": {
"field": "id",
"size": 10
},
"aggs": {
"document_first_interval": {
"filter": {
"range": {
"date": {
"gte": "2020-04-23"
}
}
}
},
"document_second_interval": {
"filter": {
"range": {
"date": {
"gte": "2020-04-22",
"lt": "2020-04-23"
}
}
}
},
"select_bucket": {
"bucket_selector": {
"buckets_path": {
"first_interval": "document_first_interval._count",
"second_interval": "document_second_interval._count"
},
"script": "if(params.first_interval==0||params.second_interval==0) return true;"
}
}
}
}
}
}
````
<b>Result:</b>
````
"aggregations" : {
"ids" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : 2,
"doc_count" : 1,
"document_second_interval" : {
"doc_count" : 0
},
"document_first_interval" : {
"doc_count" : 1
}
}
]
}
}
````