首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在ElasticSearch中存储与时间相关的数据

在ElasticSearch中存储与时间相关的数据
EN

Stack Overflow用户
提问于 2021-02-15 04:43:59
回答 1查看 160关注 0票数 1

我想将与时间相关的数据存储在ElasticSearch中。每个文档都有一个开始时间和一个结束时间,这两个时间定义了相关的时间(例如,打开的票据)。然后,我希望能够运行查询,例如:

  1. 展示1月5日至2月2日期间的所有门票。
  2. 在多个字段上显示在某个时间范围内打开的所有票证的面

由于我将有每月索引,跨越一个月以上的文档将存储在多个索引中。

例如,1月至4月间打开的票证需要存储在所有4个月索引的索引中。

我想知道以后是否有一种简单的方法可以在索引之间的聚合上运行,这些索引知道只考虑每一张票证一次(对于faceting之类的)。

例如,如果我有以下票:

  1. A票开放时间为2021年1月1日至2021年1月17日。
  2. B票开放时间为2021年1月15日至2021年2月16日。
  3. C票于2021年/12/1/16/3/2021年开放。

我们将有下列文件/索引:

代码语言:javascript
复制
Index January:  
  {id: A, StartDate: 1/1/2021, EndDate: 17/1/2021}
  {id: B, StartDate: 15/1/2021}
  {id: C, StartDate: 12/1/2021}
Index February:  
  {id: B, StartDate: 15/1/2021, EndDate: 16/2/2021}
  {id: C, StartDate: 12/1/2021}
Index March:  
  {id: C, StartDate: 12/1/2021, endDate: 16/3/2021}

任何与用ElasticSearch实现这样一件事的最佳方式相关的输入都是最受欢迎的。如果有其他更好的数据库用于高规模和快速聚合的工作,我也会很高兴听到关于替代方案的消息。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-15 22:48:09

如果满足这些条件的,这将是非常简单的:

  1. 每个文档都有一个StartDate值。
  2. 每个文档都有一个EndDate 也有一个StartDate

因此,如果我们建立一个涵盖未来所有月度指数的索引模板

代码语言:javascript
复制
PUT _index_template/monthly-indices
{
  "index_patterns": [
    "index-2021-*"
  ],
  "template": {
    "mappings": {
      "properties": {
        "id": {
          "type": "keyword"
        },
        "StartDate": {
          "type": "date",
          "format": "d/M/yyyy"
        },
        "EndDate": {
          "type": "date",
          "format": "d/M/yyyy"
        }
      }
    }
  }
}

然后,我们可以从您的问题中添加示例文档:

代码语言:javascript
复制
POST index-2021-01/_doc/A
{
  "id": "A",
  "StartDate": "1/1/2021",
  "EndDate": "17/1/2021"
}

POST index-2021-01/_doc/B
{
  "id": "B",
  "StartDate": "15/1/2021"
}

POST index-2021-02/_doc/B
{
  "id": "B",
  "StartDate": "15/1/2021",
  "EndDate": "16/2/2021"
}

POST index-2021-02/_doc/C
{
  "id": "C",
  "StartDate": "12/2/2021"
}

POST index-2021-03/_doc/C
{
  "id": "C",
  "StartDate": "12/2/2021",
  "EndDate": "16/3/2021"
}

在那之后,问题是“哪一张票是在2021年1月1日至2021年3月31日之间开放的?”然后可以通过以下方式回答:

代码语言:javascript
复制
POST index-2021-*/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "StartDate": {
              "gte": "1/1/2021"
            }
          }
        },
        {
          "range": {
            "EndDate": {
              "lte": "31/3/2021"
            }
          }
        }
      ]
    }
  }
}

它返回docs ABC --但显然只有那些同时具有开始日期和结束日期的条目。

接下来,可以使用此date_histogram聚合构造一个简单的“面”统计数据,表示“每个月开放多少张票”:

代码语言:javascript
复制
POST index-2021-*/_search
{
  "size": 0,
  "aggs": {
    "open_count_by_months": {
      "date_histogram": {
        "interval": "month",
        "format": "MMMM yyyy", 
        "script": """
          def start = doc['StartDate'].value;
          def end = doc['EndDate'].size() == 0 ? null : doc['EndDate'].value;
          
          if (end == null) {
            return start
          }
          
          return end
        """
      }
    }
  }
}

屈服

代码语言:javascript
复制
"aggregations" : {
  "open_count_by_months" : {
    "buckets" : [
      {
        "key_as_string" : "January 2021",
        "key" : 1609459200000,
        "doc_count" : 2
      },
      {
        "key_as_string" : "February 2021",
        "key" : 1612137600000,
        "doc_count" : 2
      },
      {
        "key_as_string" : "March 2021",
        "key" : 1614556800000,
        "doc_count" : 1
      }
    ]
  }
}

最后,如果您能够在多个索引中对文档的内容“分散”保持可靠的控制,您就会没事的。

但是,如果您只是让cron作业每天同步票证并构造您的文档,它们的行为就像“宣布”当前票证状态的消息,即:

代码语言:javascript
复制
{
  "ticket_id": A,
  "status": "OPEN"
  "timestamp": 1613428738570
}

它将介绍我刚才讨论过的一些令人讨厌的复杂性-- 这里这里

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66202816

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档