2011-08-17 146 views
4

我使用elasticsearch索引和搜索位置,而且我通过操作小时运行到1个具体问题与过滤,我不知道如何制定出过滤搜索结果与elasticsearch

基本上,每个地点都有营业时间(一周中的每一天),每天可能有超过1个“营业时间”(现在我们使用2个)。

例如: 星期一: 上午9时开/关12点 下午1:00开/关晚上9点

鉴于目前的时间和一周的当天,我需要寻找“打开”位置。

我不知道我应该怎么指数随位置的详细信息,这些工作小时在一起,以及如何使用它们来筛选出来的结果还没有,任何帮助,建议将非常感激

问候

回答

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

UPDATE奇怪的是,我现在不能复制NPE - 这个查询似乎正常工作都在0.17.5和以上版本。一定是暂时的小故障。

克林特

+0

感谢克林特,这看起来非常整齐,我是跟踪您在ElasticSearch上发布的问题。 – mr1031011

+0

感谢您的更新 – mr1031011

0

最简单的方法是在位置打开时命名和索引时间片。首先,您需要提出一个架构,在位置可以打开时为每个时段分配一个名称。例如,星期四thu17可能代表5PM。然后在您的示例中的位置应该包含几个包含以下值的字段“open”:mon09,mon10,mon11,mon13,mon14,mon15,mon16,mon17,mon18,mon19,mon20,tue09,tue10等等。要仅显示周四上午7点打开的位置,只需将此过滤器添加到您的查询中:open:thu07。

您不必使用这个特定的命名模式。例如,您可以只计算一周开始的小时数。在这种情况下,星期一上午9点​​是9点,11点在周一 - 23点,周二凌晨2点 - 26点,依此类推。

+0

有趣,但约7:01或7:17,例如什么呢? 我目前的(规划)解决方案是为每天的开放时间/关闭时间(对)编制索引,然后使用弹性查询或范围(gte,lte)过滤器 – mr1031011

+0

您真的有位置在7:01开放吗?通常是一个小时或半小时,在最坏的情况下可能是四分之一。 – imotov

+0

以下是关于数值范围查询如何工作的一些背景信息:http://lucene.apache.org/java/3_0_3/api/all/org/apache/lucene/search/NumericRangeQuery.html对于做出最终决定可能有帮助。 – imotov

1

,如果你有一些是开放的2-4在周一和6-8在周二然后做一个过滤器上周一6将返回文档上述解决方案不会因为工作。下面是一些pseudojson来说明它应该如何完成。

{ 
    "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) 
        } 
       } 
      } 
     ] 
    } 
} 

所有时间应使用标准时区(GMT)在24小时格式

+0

编辑在一天内多次考虑。应该很快发布。 – Commander

+0

您的评论不正确,并且忽略了我使用“嵌套”字段类型而不是普通“对象”的事实。 “嵌套”对象在内部作为单独的文档进行索引,以避免您遇到的问题。 – DrTech

+0

嵌套对象不是免费的。如果你能避免它们(你可以在这种情况下),那么你应该。 – Commander