elasticsearch Elasticsearch-如何查询特定字段随时间变化的结果
我将在前言中声明我是elasticsearch的新手,因此这可能有一个简单的答案。到目前为止,我读到的任何东西都不能让我实现以下目标 一个非常简化的场景。我有一系列用户活动,如下所示:
elasticsearch Elasticsearch-如何查询特定字段随时间变化的结果,
elasticsearch,lucene,
elasticsearch,Lucene,我将在前言中声明我是elasticsearch的新手,因此这可能有一个简单的答案。到目前为止,我读到的任何东西都不能让我实现以下目标 一个非常简化的场景。我有一系列用户活动,如下所示: timestamp: t0, user: mike, result: failed timestamp: t1, user: anne, result: failed timestamp: t2, user: bob, result: success timestamp: t3, user: tom, res
timestamp: t0, user: mike, result: failed
timestamp: t1, user: anne, result: failed
timestamp: t2, user: bob, result: success
timestamp: t3, user: tom, result: success
timestamp: t4, user: jane, result: failed
timestamp: t5, user: anne, result: success
timestamp: t6, user: tom, result: failed
timestamp: t7, user: jane, result: failed
timestamp: t8, user: mike, result: success
我需要确定所有必须努力工作才能获得成功结果的用户(我忽略了那些从未成功的用户)。为此,我真正需要做的就是查找用户在成功之前失败一次或多次的记录
按照上面的顺序,结果是那些用户为“anne”或用户为“mike”的记录
我们忽略了“简”,因为没有成功;我们忽略了“鲍勃”,因为没有失败。我们也会忽略“汤姆”,因为他们先成功后失败——这又是另一种情况
我可以在SQL中相对容易地做到这一点,但我很难在elasticsearch中实现这一点
您将如何形成一个查询来回答这个问题
或者,更好的是,我如何重新表述我的问题以达到相同的结果
谢谢 大问题。我花了一点功夫才弄明白,但我还是设法用ES2.0中的新版本让它工作起来 我必须将时间戳更改为
“integer”
类型才能让它工作(不过它也可以与日期一起工作)
我创建了一个简单的索引,并使用\u bulk
请求添加了您的数据:
PUT /test_index
POST /test_index/doc/_bulk
{"index":{"_id":1}}
{"timestamp": 0,"user":"mike","result":"failed"}
{"index":{"_id":2}}
{"timestamp": 1,"user":"anne","result":"failed"}
{"index":{"_id":3}}
{"timestamp": 2,"user":"bob","result":"success"}
{"index":{"_id":4}}
{"timestamp": 3,"user":"tom","result":"success"}
{"index":{"_id":5}}
{"timestamp": 4,"user":"jane","result":"failed"}
{"index":{"_id":6}}
{"timestamp": 5,"user":"anne","result":"success"}
{"index":{"_id":7}}
{"timestamp": 6,"user":"tom","result":"failed"}
{"index":{"_id":8}}
{"timestamp": 7,"user":"jane","result":"failed"}
{"index":{"_id":9}}
{"timestamp": 8,"user":"mike","result":"success"}
然后我可以通过下面的查询得到你想要的(我想)。在顶级的“用户术语”
聚合下,我可以设置三个子聚合:
选择具有“failed_filter”
”的文档,然后子聚合查找该组中的最大时间戳李>“result:”failed“
选择具有“success\u filter”
的文档,然后子聚合查找该组中的最大时间戳李>“result”:“success”
- 最后,
仅选择附加到失败值的(最大)时间戳小于附加到成功值的(最大)时间戳的文档“failed\u lt\u success\u filter”
您是否可以设想有一个不同的域模型,其中每个用户有一个文档和一个时间戳结果数组,如
{“user”:“mike”,“results”:[{“timestamp”:“t0”,“result”:“failed”},{“timestamp”:“t8”,“result”:“success”}}
?或者你真的希望每个事件都有离散的文档吗?我一点也不喜欢域模型——就我们当前的数据处理而言,当前的结构更容易使用,但很乐意寻找替代方案。您提议的结构将如何使用?谢谢Sloan,这让我对如何使用多个过滤器有了更好的了解!timestamp字段将是一个真实的时间戳,很抱歉我的伪数据会让您失望。您的查询返回带扣的结果-如果我只想要匹配的记录而不需要任何聚合呢?很好的解决方案@SloanAhrens@Andrew,您可以添加另一个top\u hits
aggregation作为user\u terms
聚合的子聚合,您将获得匹配的文档。
POST /test_index/_search
{
"size": 0,
"aggregations": {
"user_terms": {
"terms": {
"field": "user"
},
"aggs": {
"failed_filter": {
"filter": { "term": { "result": "failed" } },
"aggs": {
"max_timestamp": { "max": { "field": "timestamp" } }
}
},
"success_filter": {
"filter": { "term": { "result": "success" } },
"aggs": {
"max_timestamp": { "max": { "field": "timestamp" } }
}
},
"failed_lt_success_filter": {
"bucket_selector": {
"buckets_path": {
"failed_timestamp": "failed_filter.max_timestamp",
"success_timestamp": "success_filter.max_timestamp"
},
"script": "failed_timestamp < success_timestamp"
}
}
}
}
}
}
{
"took": 11,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 9,
"max_score": 0,
"hits": []
},
"aggregations": {
"user_terms": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "anne",
"doc_count": 2,
"success_filter": {
"doc_count": 1,
"max_timestamp": {
"value": 5
}
},
"failed_filter": {
"doc_count": 1,
"max_timestamp": {
"value": 1
}
}
},
{
"key": "mike",
"doc_count": 2,
"success_filter": {
"doc_count": 1,
"max_timestamp": {
"value": 8
}
},
"failed_filter": {
"doc_count": 1,
"max_timestamp": {
"value": 0
}
}
}
]
}
}
}