Хранение моих данных в ElasticSearch и рекомендации по фильтрации - PullRequest
0 голосов
/ 28 мая 2019

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

У меня есть конечная точка API, которая позволяет пользователям искать компании по названию и возвращает результаты в следующем формате:

{
    "company": {
        "name": "KFC",
        "status": "running",
        "Cuisine": "Kentucky Fried Chicken"
    },
    "mainRestaurant": {
        "location": {
            "road": "main road",
            "city": "New York City",
            "state": "New York",
            "country": "USA"
        },
        "status": "running",
        "type": "Flagship restaurant"
    }
}

Эти данные собираются из базы данных компании и базы данных ресторана.mainRestaurant выбирается из списка ресторанов на основе следующих критериев: * Если есть флагманский ресторан, используйте его.* Если нет, то используйте первый ресторан, найденный в базе данных, где есть определенный флаг с именем important, установленный в значение true.* Если ни одного из них нет, выберите первый, который вы найдете в базе данных.

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

Что я хочу сделать, так это взять один результат из Elasticsearch для каждой компании за поиск иМой план состоял в том, чтобы добавить один результат для каждой компании в каждом месте.Таким образом, индекс будет содержать только основной ресторан для KFC (и каждой другой компании) в каждом месте.Таким образом, для Нью-Йорка он будет хранить вышеупомянутый результат, а затем для Лондона, он может иметь результат, который выглядит следующим образом:

{
    "company": {
        "name": "KFC",
        "status": "running",
        "Cuisine": "Kentucky Fried Chicken"
    },
    "mainRestaurant": {
        "location": {
            "road": "main road",
            "city": "London",
            "state": "England",
            "country": "UK"
        },
        "status": "running",
        "type": "important restaurant"
    }
}

Проблема здесь заключается в том, что в Elasticsearch имеется несколько результатов для каждой компании.без простого способа получить лучший в одном запросе.Мое решение для этого было добавить обертку вокруг объекта с некоторыми метаданными.Итак, для первого результата (флагман KFC):

{
    "bestRestaurantIn": ["*", "USA", "New York", "New York City"],
    "result": {
        ... data ...
    }
}

А для важного лондонского ресторана это будет выглядеть так:

{
    "bestRestaurantIn": ["UK", "England", "London"],
    "result": {
        ... data ...
    }
}

А для лучшего ресторана в Манчестере этобудет выглядеть так:

{
    "bestRestaurantIn": ["Manchester"],
    "result": {
        ... data ...
    }
}

Так что, если вы не передадите местоположение, я мог бы добавить условие термина, где было *, так что для компании "KFC" только тот, который имеет* в поле bestRestaurantIn будет возвращено при выполнении поиска.Если вы передадите «Манчестер» в качестве фильтра местоположения, он получит только KFC в Манчестере, потому что в Манчестере должен быть только один результат для KFC.

Вот несколько примеров поиска «kf» в названии.Он должен давать:

  • Когда фильтр местоположения пуст -> должен быть возвращен флагманский ресторан в Нью-Йорке, поскольку он является главным главным рестораном KFC
  • Когда фильтром местоположения является Нью-Йорк-> Флагманский ресторан в Нью-Йорке, поскольку он является главным рестораном в Нью-Йорке для KFC.
  • Если в качестве фильтра местоположения выбран Манчестер -> KFC в Манчестере следует вернуть.

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

Это решение работает правильно.Тем не менее, это становится проблемой, когда добавляется больше фильтров.Каждый ресторан в базе данных ресторанов имеет статус.Который может быть либо «работающим», либо «выключенным».Это означает, что нам нужно добавить «работающий» ресторан и «закрытый» ресторан (где он есть) для каждой компании в каждом месте.Нам также нужно добавить флаг к оболочке, который выглядит как «isBestWithNoFilters», что, вероятно, будет «работающим» рестораном.

Моя проблема в том, что это не очень хорошо масштабируется. Если мне нужно добавить несколько на уровне ресторана, это станет невероятно сложным. Есть ли образец, которому я должен следовать для этого?

Извините за длинный пост. Надеюсь, я дал понять!

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