我在elasticsearch中有一个企业索引。索引中的每个文档代表一个企业,每个企业都有营业时间。我正在尝试允许使用星期几和时间对工作时间进行筛选。例如,我们希望能够对星期二晚上6:00之后开放的show we all business进行筛选,我认为我们应该有一个具有以下Map的字段:
{
"mappings": {
"properties": {
"business_hours": {
"type": "date_range",
"format": "w'T'hh:mma"
}
}
}
}
每个文档都会有一系列的工作时间。因此,周一上午9:00-下午5:00和周二上午9:30-下午5:00营业的商店如下所示:
POST my-index/_doc
{
"name": "My Store",
"business_hours": [
{
"gte": "1T09:00AM",
"lte": "1T05:00PM"
},
{
"gte": "2T09:30AM",
"lte": "2T05:00PM"
}
]
}
我试着搜索这个文档并查询它,但是小时过滤器不起作用,它们看起来好像被忽略了。。。。elasticsearch是否支持按一周中的某一天进行过滤,或者它是否需要是一个实际的日期时间?
这是我使用的查询。它本应过滤周三开放的业务,但它返回了上面只有周一和周二营业时间的文档
GET my-index/_search
{
"query": {
"bool": {
"filter": [
{
"range": {
"business_hours": {
"gte": "3T10:00AM",
"lte": "3T05:00PM",
"relation": "CONTAINS"
}
}
}
]
}
}
}
2条答案
按热度按时间7gs2gvoe1#
使用
range
田野是个好地方。但是date_range
,在绝对日期有效,我建议使用integer_range
现场。由于每天包含1440分钟,我的建议是将开放时间编码为午夜后的分钟数,并在该数字前面加上当天的索引(星期一=1,星期二=2,等等)。从午夜开始将给定的小时转换成分钟的公式非常简单:
以你上面的例子来说,它会产生这样的结果:
那样的话
range
查询变得很简单,它可以消除任何与日期相关的问题。例如,下面的查询通过搜索星期一早上6点到下午5点营业的业务来检索上面的文档vuv7lop32#
我可以用Map、示例数据和查询重现这个问题,当我在查询中使用explain时,它解释了为什么要获取第1天和第2天的结果。
带explain的搜索查询输出
如果您仔细注意,查询将转换为如下所示的epoch格式
现在,当您使用epoch转换器时,您可以注意到它实际上在一个完全不同的日期范围上进行范围查询,起始范围是
Friday, 10 December 1971 07:59:59
根据日期字段上的范围查询,elasticsearch添加了缺少的日期组件,这似乎是导致问题的原因。如果你给出适当的数据范围(即完整的日期,包括年,月等),显然它的工作,但我同意,这将导致复杂性,我将看看我们如何实现与给定的格式相同的事情。