使用 Python DSL 在 Elasticsearch 中按日期范围过滤数据

问题描述

我在下面写了这个方法来过滤过去 8 天的数据

def method_one(query) -> Query:
    gte = (datetime.datetime.Now() - datetime.timedelta(days=query)).date()
    lt = (datetime.datetime.Now()).date()
    print(gte,lt)
    return Q(MultiMatch(
        query=filter("range",{"lastModifiedDate": {"gte": gte,"lt": lt}}
                        ),fields=['lastModifiedDate']
    ))

我想通过在 Python 中形成一个 Elasticsearch lastModifiedDate 对象来根据 Query 字段过滤数据。 例如,如果我给出 /lastModifiedDate=8(Rest API 调用),它应该通过过滤过去 8 天返回数据。

解决方法

您不需要 datetime 模块在 Elasticsearch 中构建日期查询——您可以使用 built-in date math

from json import dumps
from elasticsearch_dsl.search import Search
from elasticsearch_dsl.query import Q,MultiMatch


def date_range_query(num_of_days):
    if not isinstance(num_of_days,int):
        raise Exception(
            'expected numeric & positive `num_of_days`,got `%s`' % str(num_of_days))

    return Q(
        "range",lastModifiedDate={
            "gte": "now-%dd" % num_of_days,"lt": "now"
        }
    )


try:
    q = date_range_query(8)
    print(dumps(q.to_dict(),indent=2))
except Exception as e:
    print(e)

哪个会打印

{
  "range": {
    "lastModifiedDate": {
      "gte": "now-8d","lt": "now"
    }
  }
}

或者,如果您坚持使用 datetime.date 对象,则需要先对日期进行字符串化。现在,当您使用 str(...) 执行此操作时,您实际上是在调用 .__str()__,然后调用 .isoformat() 并返回一个格式为 YYYY-MM-DD 的字符串。

现在,您的 lastModifiedDate 字段的映射可能具有不同的格式。因此,声明您的 range 查询的格式是一种很好的做法:

gte = (datetime.datetime.now() - datetime.timedelta(days=num_of_days)).date()
lt = (datetime.datetime.now()).date()

return Q(
    "range",lastModifiedDate={
        "gte": str(gte),"lt": str(lt),"format": "yyyy-MM-dd"  # keep in mind that the format in ES conforms to Java syntax,not python
    }
)

它会产生一个类似的查询,但有具体的、拼写出来的日期:

{
  "range": {
    "lastModifiedDate": {
      "gte": "2021-02-26","lt": "2021-03-06","format": "yyyy-MM-dd"
    }
  }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...