查询以提取超过30米前更新的时间戳不起作用

时间:2017-08-18 22:38:32

标签: elasticsearch

我试图解决这个问题。一切似乎都要结束,但它没有按照我的期望工作:(

我的索引test-index包含以下文件:

{
        "_index": "test-index",
        "_type": "testType",
        "_id": "AV33b_VYUyX1XZAq7NTI",
        "_score": 1,
        "_source": {
          "timestamp": "2017-08-17T17:56:55"
        }
      },
      {
        "_index": "test-index",
        "_type": "testType",
        "_id": "AV33cBN4UyX1XZAq7NTJ",
        "_score": 1,
        "_source": {
          "timestamp": "2017-08-18T17:11:12"
        }
      },
      {
        "_index": "test-index",
        "_type": "testType",
        "_id": "AV33cetJUyX1XZAq7NTK",
        "_score": 1,
        "_source": {
          "timestamp": "2017-08-19T17:11:12"
        }
      }

在这里我可以看到

  1. 理论上昨天更新的文件。
  2. 最近更新的文件(08/18)20分钟前(现在=写这篇文章的时间是17:30)
  3. 明天“最后更新”的文件,只是为了说明为什么我不知道为什么这不起作用。
  4. 我有以下查询:

    GET test-index/testType/_search?pretty
    {
      "query": {
        "range": {
          "timestamp": {
            "lte": "now-30m"
          }
        }
      }
    }
    

    它拉动了今天(20分钟前)更新的记录,以及昨天更新的记录。我原以为它只会在昨天拉开纪录。

    "hits": {
        "total": 2,
        "max_score": 1,
        "hits": [
          {
            "_index": "test-index",
            "_type": "testType",
            "_id": "AV33b_VYUyX1XZAq7NTI",
            "_score": 1,
            "_source": {
              "timestamp": "2017-08-17T17:56:55"
            }
          },
          {
            "_index": "test-index",
            "_type": "testType",
            "_id": "AV33cBN4UyX1XZAq7NTJ",
            "_score": 1,
            "_source": {
              "timestamp": "2017-08-18T17:11:12"
            }
          }
        ]
    

    将查询更改为gte now-30m,它按预期工作,并使用明天的时间戳拉取记录。如果我将其更改为lte now-1d,范围查询也能正常工作,只显示预期的08/17记录,但我想使用一分钟截止。当我尝试做几个小时时,也可以观察到同样的错误行为。

    我尝试将格式设置为yyyy-MM-dd HH:mm:ss并接受ES的默认日期映射,但没有运气。

    有人知道这里可能有什么问题吗?

    编辑:它似乎也为“今天”提供了记录,但也是未来的一段时间,例如:

     {
            "_index": "test-index",
            "_type": "testType",
            "_id": "AV33gSs6UyX1XZAq7NTS",
            "_score": 1,
            "_source": {
              "timestamp": "2017-08-18 19:11:12"
            }
          }
    

    这似乎是一个精确的问题,我只是不知道问题是什么,因为一切似乎都是正确的。

1 个答案:

答案 0 :(得分:1)

我想我最终发现了根本原因是什么。索引文档时,ES将提供的值视为UTC日期/时间。在查询时,ES使用now的UTC日期/时间与索引的时间戳进行比较。

鉴于我比UTC晚了5个小时并且我使用我的本地日期/时区索引文档,我的查询基本上是说"给我的日期不到5小时 - 从现在起30分钟。

这是我最后编写的查询,以查看字面上比较的值,以及我必须做些什么来实现"期望" bool查询中的结果:

GET test-index/testType/_search?pretty
{
  "query": {
    "bool" : {
      "must" : {
        "script" : {
          "script" : {
            "inline": "doc['timestamp'].value < new Date().getTime() - (5 * 60 * 60 * 1000) - (120 * 60 * 1000)",
            "lang": "painless"
           }
        }
      }
    }
  },
  "script_fields": {
    "timestampValue" : {
      "script" : "doc['timestamp'].value"
    },
    "valueTimestampMustBeLessThan" : {
      "script" : "new Date().getTime() - (120 * 60 * 1000)"
    },
    "now" : {
      "script" : "new Date().getTime()"
    },
    "subtract": {
      "script": "(120 * 60 * 1000)"
    },
    "timestamp" : {
      "script" : "doc['timestamp']"
    },
    "lt?" : {
      "script" : "doc['timestamp'].value < new Date().getTime() - (120 * 60 * 1000)"
    },
    "gt?" : {
      "script" : "doc['timestamp'].value > new Date().getTime() - (120 * 60 * 1000)"
    }
  }
}

一个例子:

  • 我在下午6:40左右在08/18点插入的文件读取其UTC时间及其本地&#34;时间是下午1:40。
  • 我在2017年8月8日下午6:41左右运行的查询将now的UTC时间显示为晚上11:41,以及其本地&#34;时间是下午6:41。

ES文档中有很多地方提到它使用UTC中的日期,例如:

但直到现在我才完全理解其含义。

在我正在做的事情中,我只需要确保我的应用程序插入UTC时间,特别是在时区不同的情况下。