我正在使用elasticsearch来索引和搜索位置,我遇到了一个特殊问题,即按操作时间过滤,我不知道如何解决
基本上,每个地点都有营业时间(一周中的每一天),每天可能有超过1套“营业时间”(我们现在使用2个)。
例如: 星期一: 上午9点开放/关闭12点 开放时间为下午1点/晚上9点
鉴于当前时间和当周的当天,我需要搜索“开放”位置。
我不知道如何将这些营业时间与位置详细信息一起索引,以及如何使用它们来过滤掉结果,任何帮助,建议都会非常感激
此致
答案 0 :(得分:4)
更好的方法是使用nested
文档。
首先:设置映射以指定hours
文档应被视为嵌套:
curl -XPUT 'http://127.0.0.1:9200/foo/?pretty=1' -d '
{
"mappings" : {
"location" : {
"properties" : {
"hours" : {
"include_in_root" : 1,
"type" : "nested",
"properties" : {
"open" : {
"type" : "short"
},
"close" : {
"type" : "short"
},
"day" : {
"index" : "not_analyzed",
"type" : "string"
}
}
},
"name" : {
"type" : "string"
}
}
}
}
}
'
添加一些数据:(注意营业时间的多个值)
curl -XPOST 'http://127.0.0.1:9200/foo/location?pretty=1' -d '
{
"name" : "Test",
"hours" : [
{
"open" : 9,
"close" : 12,
"day" : "monday"
},
{
"open" : 13,
"close" : 17,
"day" : "monday"
}
]
}
'
然后运行您的查询,按当前日期和时间进行过滤:
curl -XGET 'http://127.0.0.1:9200/foo/location/_search?pretty=1' -d '
{
"query" : {
"filtered" : {
"query" : {
"text" : {
"name" : "test"
}
},
"filter" : {
"nested" : {
"path" : "hours",
"filter" : {
"and" : [
{
"term" : {
"hours.day" : "monday"
}
},
{
"range" : {
"hours.close" : {
"gte" : 10
}
}
},
{
"range" : {
"hours.open" : {
"lte" : 10
}
}
}
]
}
}
}
}
}
}
'
这应该有效。
不幸的是,在0.17.5中,它会抛出一个NPE - 它很可能是一个简单的bug,很快就会修复。我在这里打开了一个问题:https://github.com/elasticsearch/elasticsearch/issues/1263
更新奇怪的是,我现在无法复制NPE - 此查询似乎在版本0.17.5及更高版本上都能正常工作。一定是一些暂时的故障。
奇
答案 1 :(得分:1)
上述解决方案不起作用,因为如果你有一些在星期一开放2-4和星期二6-8开放的东西,那么在星期一6点进行过滤将返回文件。下面是一些伪json来说明它应该如何完成。
{
"business_document": "...",
"hours": {
"1": [
{
"open": 930,
"close": 1330
},
{
"open": 1530,
"close": 2130
}
],
"2": [
{
"open": 1000,
"close": 2100
}
],
"3": [
{
"open": 1000,
"close": 2100
}
],
"4": [
{
"open": 1000,
"close": 2100
}
],
"5": [
{
"open": 1000,
"close": 2100
}
],
"6": [
{
"open": 1000,
"close": 2100
}
],
"7": [
{
"open": 930,
"close": 1330
},
{
"open": 1530,
"close": 2130
}
]
}
}
Sample Filter (can be applied to any query for a businesses):
{
"filter": {
"and": [ //Must match all following clauses
{
"range": {
"hours.1.open": { //Close Hour of Day 1 (current day)
"lte": 1343 //Store open time is less than 13:43 (current time)
}
}
},
{
"range": {
"hours.1.close": { //Close Hour of Day 1 (current day)
"gte": 1343 //Store close time is greater than 13:43 (current time)
}
}
}
]
}
}
所有时间都应采用24小时格式,使用标准时区(GMT)
答案 2 :(得分:0)
最简单的方法是在位置打开时命名和索引时隙。首先,您需要提供一个模式,在可以打开位置时为每个时隙分配一个名称。例如,thu17可能代表星期四下午5点。然后,您的示例中的位置应使用包含以下值的几个“open”字段编制索引:mon09,mon10,mon11,mon13,mon14,mon15,mon16,mon17,mon18,mon19,mon20,tue09,tue10等等。要仅显示星期四早上7点开放的位置,您只需将此过滤器添加到您的查询中:open:thu07。
您不必使用此特定命名架构。例如,您可以计算从一周开始的小时数。在这种情况下,星期一上午9点将是星期一9点,晚上11点 - 星期二23点,凌晨2点,星期二 - 26,依此类推。