SGo*_*lds 5 elasticsearch elasticsearch-dsl
我在 Elasticsearch 中有一个企业索引。索引中的每个文档代表一个企业,每个企业都有business_hours。我试图允许使用星期几和时间来过滤营业时间。例如,我们希望能够做一个过滤器来显示周二晚上 6:00PM 之后开放的所有业务, 我认为我们应该有一个具有以下映射的字段:
{
"mappings": {
"properties": {
"business_hours": {
"type": "date_range",
"format": "w'T'hh:mma"
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
每个文档都会有一个business_hours 数组。因此,周一上午 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"
}
]
}
Run Code Online (Sandbox Code Playgroud)
我尝试搜索此文档并查询它,但是时间过滤器不起作用,它们看起来像是被忽略了......Elasticsearch 是否支持按一周中的某一天进行过滤,或者是否需要是实际的日期时间?
这是我使用的查询。它应该过滤周三营业的营业时间,但它返回了上面的文件,其中只有周一和周二的营业时间
GET my-index/_search
{
"query": {
"bool": {
"filter": [
{
"range": {
"business_hours": {
"gte": "3T10:00AM",
"lte": "3T05:00PM",
"relation": "CONTAINS"
}
}
}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用字段的想法range是个好主意。但是,date_range我建议使用字段,而不是适用于绝对日期的integer_range。
由于每天包含 1440 分钟,我的建议是将开放时间编码为自午夜以来的分钟数,并在该数字前加上当天的索引(星期一 = 1、星期二 = 2 等)。将给定的小时转换为自午夜以来的分钟的公式非常简单:
(60 * HH) + MM
Note: HH is in 24 hours format, not AM/PM, but that's a detail
Run Code Online (Sandbox Code Playgroud)
以上面的例子为例,它会产生这样的结果:
POST my-index/_doc
{
"business_hours": [
{
"gte": 10540, <--- Monday (1), 540 minutes after midnight
"lte": 11020 <--- Monday (1), 1020 minutes after midnight
},
{
"gte": 20570, <--- Tuesday (2), 570 minutes after midnight
"lte": 21020 <--- Tuesday (2), 1020 minutes after midnight
}
]
}
Run Code Online (Sandbox Code Playgroud)
这样range查询就变得很简单,可以消除任何与日期相关的问题。例如,下面的查询通过搜索周一早上 6 点到下午 5 点营业的企业来检索上面的文档
GET my-index/_search
{
"query": {
"bool": {
"filter": [
{
"range": {
"business_hours": {
"gte": "10600", <--- Monday (1), 600 minutes after midnight
"lte": "11020", <--- Monday (1), 1020 minutes after midnight
"relation": "CONTAINS"
}
}
}
]
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1735 次 |
| 最近记录: |