我会考虑这样做如下:
- 营业时间和营业时间是Elasticsearch中嵌套对象数组的整数值:
例如:商店在第1天的07:00开店,在13:30关门,然后在14:30开店,在18:00关门,将在ES中转换为:
"shop_name": "Shop 1","open_hours": [ { "open": 420, "close": 810 }, { "open": 870, "close": 1080 }]一周中的每一天(1-> 7)代表一个值(将添加到分钟数中):
Day 1 = addition 0
Day 2 = addition 2000
Day 3 = addition 4000
…
Day 7 = addition 10000
因此,每天增加2000,因为每天最多包含1440分钟(24小时* 60分钟),并且为了能够将一天与单个数字区分开,这些数字不必相交。
因此,上面示例中商店在07:00开张的示例将在第4天转换为:
"shop_name": "Shop 1", "open_hours": [ { "open": 6420, "close": 6810 }, { "open": 6870, "close": 7080 } ]查询这些文档时,您要搜索的那一天需要遵循与上述相同的规则。例如,如果要查看是否在第4天的13:45打开了“商店1”,则可以搜索(6000 + 13 * 60 + 45 = 6825)分钟。
Elasticsearch中上述所有内容的映射如下:
{ "mappings": { "shop" : { "properties": { "shop_name" : { "type" : "string" }, "open_hours" : { "type" : "nested", "properties": { "open" : { "type" : "integer" }, "close": { "type" : "integer" } } } } } } }- 测试数据:
POST /shops/shop/_bulk {"index":{}} {"shop_name":"Shop 1","open_hours":[{"open":420,"close":810},{"open":870,"close":1080}]} {"index":{}} {"shop_name":"Shop 2","open_hours":[{"open":0,"close":500},{"open":1000,"close":1440}]} {"index":{}} {"shop_name":"Shop 3","open_hours":[{"open":0,"close":10},{"open":70,"close":450},{"open":900,"close":1050}]} {"index":{}} {"shop_name":"Shop 4","open_hours":[{"open":2000,"close":2480}]} {"index":{}} {"shop_name":"Shop 5","open_hours":[{"open":2220,"close":2480},{"open":2580,"close":3000},{"open":3100,"close":3440}]} {"index":{}} {"shop_name":"Shop 6","open_hours":[{"open":6000,"close":6010},{"open":6700,"close":6900}]}- 查询在第二天的第2400分钟(06:40)在第二天开张的商店:
{ "query": { "bool": { "must": [ { "nested": { "path": "open_hours", "query": { "bool": { "must": [{ "filtered": { "filter": { "range": { "open_hours.open": { "lte": 2400 }}}}},{ "filtered": { "filter": { "range": { "open_hours.close": { "gte": 2400 }}}}} ] }}}} ] }}}将输出Shop 4和Shop 5:
"shop_name": "Shop 4", "open_hours": [ { "open": 2000, "close": 2480 } ] "shop_name": "Shop 5", "open_hours": [ { "open": 2220, "close": 2480 }, { "open": 2580, "close": 3000 }, { "open": 3100, "close": 3440 } ]稍后编辑: 自从我添加此回复以来,Elasticsearch有了很长的路要走,此后发生了很多变化,因此可以用a
或什至简单的替换
filtered过滤器(在
bool
must我使用的上下文中)。另外,6.x中不再存在,因此,如果您需要以某种方式使用分析器或()按商店名称进行搜索,则可以使用:
bool
filter
must``string``text``keyword``"shop_name": { "type" : "text" }, { "query": { "bool": { "must": [ { "nested": { "path": "open_hours", "query": { "bool": { "filter": [{ "range": { "open_hours.open": { "lte": 2400 } }},{ "range": { "open_hours.close": { "gte": 2400 } }} ] } } } } ] } } }


