使用超过 30m 前更新的时间戳进行拉取的查询无法正常工作

2023-12-30

我绞尽脑汁试图解决这个问题。一切似乎都很顺利,但它并没有按照我的预期工作:(

我有一个索引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. 明天“最后更新”的文档,只是为了说明为什么我很困惑为什么这不起作用。

我有以下查询:

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

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


我想我最终找到了造成这种情况的根本原因。索引文档时,ES 将提供的值视为 UTC 日期/时间。查询时,ES使用UTC日期/时间now与索引的时间戳进行比较。

鉴于我比 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)"
    }
  }
}

一个例子:

  • 我于 2017 年 8 月 18 日下午 6:40 左右插入的一份文档显示其 UTC 时间为下午 1:40,“本地”时间为下午 1:40。
  • 我于 2017 年 8 月 18 日下午 6:41 左右运行的查询显示nowUTC 时间为晚上 11:41,“本地”时间为晚上 6:41。

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

  • https://www.elastic.co/guide/en/elasticsearch/reference/current/date.html https://www.elastic.co/guide/en/elasticsearch/reference/current/date.html
  • https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html#CO160-2 https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-query.html#CO160-2

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用超过 30m 前更新的时间戳进行拉取的查询无法正常工作 的相关文章

随机推荐