Многоиндексный запрос и фильтр Elasticsearch - PullRequest
0 голосов
/ 25 апреля 2020

У меня есть 2 индекса, один из которых хранит данные о событии, а другой - о доступности этого события. Я пытаюсь создать один запрос, который получает события по запросу, но возвращает только те из них, которые доступны, и мне трудно это делать.

В индексе событий хранятся

{
  "id" : "152ce52d-e975-4ebd-849a-0a12f535e644",
  "createdAt" : 1.5519999143126902E12,
  "description" : "A very not so concise description",
  "geoHash" : "dnh00x6x5",
  "name" : "a name",
  ...etc...
}

Индекс доступности сохраняет доступность следующим образом:

{
  "eventId" : "152ce52d-e975-4ebd-849a-0a12f535e644",
  "maxGuests" : 8,
  "availability" : {
    "lte" : "2019-10-18T22:15:00.000Z",
    "gte" : "2019-10-18T02:30:00.000Z"
  }
}

Я пытаюсь создать запрос, как показано ниже, но я не могу понять, как фильтровать по спискам, которые соответствуют критериям в индексе событий И доступно в индексе доступности.

GET events,availability/_search
{
  "size": 5,
  "from": 0,
  "_source": [
      "id"
  ],
  "query": {
    "bool": {
      "must": [
        {
          "geo_distance": {
            "distance": "25mi",
            "geoHash": {
              "lat": 34.0389,
              "lon": -84.3826
            }
          }
        }
      ],
      "should": [],
      "filter":[               
        {
          "range" : {
            "availability" : { 
              "gte" : "2019-10-31",
              "lte" : "2020-11-01",
              "relation" : "within" 
            }
          }
        }
      ]
    }
  }
}

-

Причина, по которой я хочу сделать только один запрос, заключается в том, что клиент ожидает определенное указанное число событий. Если я отфильтрую недоступные события после того, как получу данные о событиях, то, скорее всего, у меня останется меньше событий, чем ожидал клиент, и мне потребуется еще один поиск, чтобы заполнить пробел.

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

1 Ответ

1 голос
/ 25 апреля 2020

То, что вы хотите выполнить sh является эквивалентом внешнего ключа SQL (объединение). Невозможно получить именно то, что вы хотите, то есть отфильтровать документы из индекса A, запросив индекс B. Ваши варианты:

  1. Как вы упомянули, решите это на уровне приложения (хотя это вызывает другие проблемы для вас, так что это не решение).
  2. Объедините данные в один индекс и дублируйте информацию о событиях. Хотя это кажется дорогостоящим, следует ожидать дублирования данных в базе данных № 1036 *. Если вам нужна реляционная модель, то, возможно, вам следует использовать решение SQL.
  3. Использовать parent / child (тип соединения) . Проблема в том, что вам нужно, чтобы данные были в общем индексе. Более того, родитель и ребенок также будут храниться в одном и том же осколке.

Один из подходов к этому (хотя и более сложный), который, я считаю, сработает для вас, заключается в использовании вложенного тип данных , который на самом деле является более компактным подходом для решения № 2 (объедините ваши данные в одном индексе, но сохраните root информацию только один раз). Сделайте события в root, и доступность появится как вложенная. Если вы хотите добавить одну доступность, вы можете использовать update api , а при запросе вы можете выполнять поиск по полям root и по вложенным. Если вам нужно получить указанные c записи о доступности для события, вы можете использовать внутренние хиты

То, что вы пытаетесь сделать (многоиндексный поиск), не присоединится к вашим данным автоматически, он не будет работать. Elasticsearch не работает таким образом, и реляционная модель не подходит для этого продукта.

И последнее: хорошо планировать заранее, но плохо пытаться оптимизировать рано .

Реальная проблема заключается в том, что программисты слишком много времени уделяют беспокойству по поводу эффективности в неправильных местах и ​​в неподходящее время; преждевременная оптимизация - это root всего зла (или, по крайней мере, большей его части) в программировании.

Интересное чтение , которое обобщает вышеприведенное

...