elasticsearch Elasticsearch-如何查询特定字段随时间变化的结果,elasticsearch,lucene,elasticsearch,Lucene" /> elasticsearch Elasticsearch-如何查询特定字段随时间变化的结果,elasticsearch,lucene,elasticsearch,Lucene" />

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

我将在前言中声明我是elasticsearch的新手,因此这可能有一个简单的答案。到目前为止,我读到的任何东西都不能让我实现以下目标

一个非常简化的场景。我有一系列用户活动,如下所示:

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
                  }
               }
            }
         ]
      }
   }
}