使用 Python DSL 在 Elasticsearch 中按日期范围过滤数据
Filter data by day range in Elasticsearch using Python DSL
我在下面写了这个方法来过滤最近 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 Query
对象来基于 lastModifiedDate
字段过滤数据。
例如,如果我给 /lastModifiedDate=8(休息 API 调用),它应该 return 通过过滤最近 8 天的数据。
在 Elasticsearch 中构建日期查询不需要 datetime
模块——您可以使用 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()__
which then calls .isoformat()
和 returns 格式为 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"
}
}
}
我在下面写了这个方法来过滤最近 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 Query
对象来基于 lastModifiedDate
字段过滤数据。
例如,如果我给 /lastModifiedDate=8(休息 API 调用),它应该 return 通过过滤最近 8 天的数据。
在 Elasticsearch 中构建日期查询不需要 datetime
模块——您可以使用 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()__
which then calls .isoformat()
和 returns 格式为 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"
}
}
}