Фильтрация результатов поиска по часам работы сasticsearch - PullRequest
4 голосов
/ 17 августа 2011

Я используюasticsearch для индексации и поиска местоположений, и я столкнулся с 1 конкретной проблемой с фильтрацией по часам работы, которую я не знаю, как работать

По сути, каждое местоположение будет иметьчас работы (для каждого дня недели), и каждый день может иметь более 1 «набора» часов работы (сейчас мы используем 2).

Например: понедельник: открытие 9:00 / закрытие 12:00, открытие 13:00 / закрытие 9:00

Учитывая текущее время и текущий день недели, мне нужно искать «открытые» места.

Я не знаю, как мне индексировать эти часы работы вместе с деталями местоположения, и как использовать их для фильтрации результатов, но любая помощь, предложение будут очень признательны

Привет

Ответы [ 3 ]

4 голосов
/ 19 августа 2011

Лучший способ сделать это - использовать 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 - скорее всего это будет простая ошибка, которая будет исправлена ​​в ближайшее время. Я открыл вопрос для этого здесь: https://github.com/elasticsearch/elasticsearch/issues/1263

ОБНОВЛЕНИЕ Как ни странно, теперь я не могу реплицировать NPE - кажется, что этот запрос корректно работает как в версии 0.17.5, так и выше. Должно быть, был какой-то временный глюк.

Клинт

1 голос
/ 16 октября 2014

Приведенное выше решение не работает, потому что если у вас есть что-то открытое 2-4 в понедельник и 6-8 во вторник, то выполнение фильтра в понедельник в 6 вернет документ.Ниже приведен псевдоджонсон, иллюстрирующий, как это должно быть сделано.

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

0 голосов
/ 18 августа 2011

Самый простой способ сделать это - назвать и индексировать временные интервалы, когда местоположение открыто. Во-первых, вам нужно придумать схему, которая присваивает имя каждому временному интервалу, когда местоположение может быть открыто. Например, 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 и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...