@ADv1S

Как организовать архитектуру для подписки по ключевым словам (как пример, Avito)?

Ситуация такая:
Имеется:
1) БД Postgres, в которой хранятся подписки пользователей ~50000 запросов. Запросы вида: Автомобили, Москва, пробег до 100 тыс., в описании есть "зимняя резина", "в родной краске".
2) Кластер ElasticSearch, в котором часто появляются новые документы - объявления. До 500 в минуту.

Задача: организовать рассылку по новым объявлениям как в avito, auto.ru.

Что происходит сейчас:
За минуту загружается ~500 новых объявлений, кладем их в ElasticSearch, и раз в минуту запускаем процесс проверки, какому пользователю какое объявление подходит. Т.е. формирую 50000 запросов к ElasticSearch с заданными id-шниками новых записей (потому что в запросах юзеров есть полнотекст, которым и занимается ES), и потихоньку, по 500 за раз выполняю их на кластере ElasticSearch. Некторые объявления удается отфильтровать на backend, например, если регион не подходит, но запросов все-равно очень много. Соответсвенно, эластик вешается от такого количества полнотекстовых запросов, и поиск по сайту начинает страшно тормозить.

Вид запросов условно такой:
1) Найти среди 500 новых объявлений те, в которых встречается словосочетание "цвет белый", в гороне Казань
2) Найти среди 500 новых объявлений те, в которых встречается "зимняя резина" или "полный электропакет", в городе Москва
........
и таких еще 49000

Есть какие-то идеи как лучше организовать такое решение с рассылкой? Или кто поделится опытом, как устроена система принятия решения, подходит ли документ пользователю или нет, у гигантов, как avito, auto.ru?
  • Вопрос задан
  • 1859 просмотров
Решения вопроса 2
  • xmoonlight
    @xmoonlight
    Сложный вопрос - мудрый ответ.
    1. Выделить из запроса сущности (имена существительные): можно использовать это
    2. Проверить по заранее подготовленному словарю синонимов и унифицировать всё, что имеет неточности и является синонимом.
    3. Делаем привязку тегов текущего объявления к ОБЩЕМУ списку тегов объявлений всей системы.
    4. Под объявлением отображаем только 5-6 тэгов, с максимальным количеством объявлений внутри каждого тега (кол-ва привязанных объявлений к этому тегу) по всей системе.
    5. В очередь пользователя для отправки - помещаем ID объявлений по его подписке: тэги и т.д.
    6. Как только пул новых объявлений превышает пороговое значение - делаем рассылку. Например, каждые 30 новых из общей очереди пользователя:
    if($newItemsForUser>=30) {
       /* 
          команда запроса инициализации рассылки
          например, команда через API микросервису
       */
    }
    Ответ написан
  • Sanasol
    @Sanasol
    нельзя просто так взять и загуглить ошибку
    Думаю логично для подписок использовать модель pubsub в любой реализации.
    И соответственно делать рассылку сразу после создания каждого объявления.
    Точнее добавлять объявления в некий пул для рассылки, и как только наберется N количество, отправлять рассылку.

    1. Создается объявление
    2. Попадает в очередь для парсинга
    3. Парсер вычленяет из объявления ключевые слова по базе подписок.
    4. Если ключевые слова находятся, то объявление отправляется в соответствующие каналы(пулы) для рассылки
    5. После того как пул набирает N количество объявлений - делается рассылка.


    В итоге должно получиться что-то вроде того что нужно.

    "Продам гараж в Москве, белый"
    Парсер нашел: москва, белый гараж
    Объявление попало в каналы: москва, белый гараж.
    И после того как наберутся остальные объявления либо когда пройдёт N времени, очередь рассылается подписчикам этих двух каналов и очищается.
    Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через TM ID
Похожие вопросы
Вакансии с Моего Круга Все вакансии
Заказы с Фрилансим Все заказы