2011-08-17 128 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