2010-03-12 3 views
8

Я создаю приложение, которое нуждается в обратном поиске. Под этим я подразумеваю, что пользователи приложения будут вводить параметры поиска и сохранять их; то, когда любые новые объекты будут введены в систему, если они соответствуют существующим параметрам поиска, сохраненным пользователем, уведомление будет отправлено и т. д.Обратный поиск лучших практик?

Мне сложно найти решения для этого типа проблем ,

Я использую Django и думать о построении запросов и засолки их с помощью объектов Q, как описано здесь: http://www.djangozen.com/blog/the-power-of-q

То, как я это вижу, когда новый объект вводится в базу данных, я должен загрузить каждый сохраненный запрос из db и каким-то образом запускать его против этого одного нового объекта, чтобы убедиться, что он будет соответствовать этому поисковому запросу ... Это не кажется идеальным - кто-нибудь решил такую ​​проблему раньше?

ответ

4

На уровне базы данных многие базы данных предлагают «триггеры».

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

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

Хороший способ для триггеров и оповещений для связи через очереди сообщений - очереди, такие как RabbitMQ и другие версии AMQP, будут масштабироваться с вашего сайта.

4

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

Более 20 лет назад мы обрабатываемся сохраненных запросов, рассматривая их в качестве minidocs и индексировать их на основе всех должны и может иметь термин. Список терминов нового документа использовался как своего рода запрос к этой «базе данных запросов», который создал список возможно интересных поисковых запросов для запуска, а затем только те поиски были запущены в отношении новых документов. Это может звучать запутанно, но когда имеется более чем несколько сохраненных запросов (скажем, от 10 000 до 1 000 000 или более), и у вас есть сложный язык запросов, который поддерживает гибрид булевого и сходного поиска, он существенно уменьшил номер, который мы должны были выполнить как полноразмерные запросы - часто не более 10 или 15 запросов.

Одна вещь, которая помогла нам в том, что мы находились под контролем horizontal and the vertical всего этого. Мы использовали наш синтаксический анализатор запросов для создания дерева синтаксического анализа и который использовался для создания списка обязательных/может иметь термины, которые мы индексировали по запросу. Мы предупредили клиента от использования определенных типов подстановочных знаков в сохраненных запросах, поскольку это может вызвать взрыв в количестве выбранных запросов.

Обновление для комментариев:

Короткий ответ: Я не знаю точно.

Более длинный ответ: мы имели дело с пользовательской текстовой поисковой системой, а часть синтаксиса запроса позволила очень эффективно отрезать коллекцию документов с особым упором на date_added. Мы играли в много игр, потому что каждый день мы глотали 4-10 000 000 новых документов и запускали их против 1 000 000 + сохраненных запросов на DEC Alphas с 64 МБ основной памяти. (Это было в конце 80-х/начале 90-х годов.)

Я предполагаю, что фильтрация на что-то эквивалентное date_added может быть сделано использоваться в комбинации даты последнего времени вы запускали свои запросы, или, может быть, самый высокий id в последнее время выполнения запроса. Если вам нужно повторно запустить запросы с измененной записью, вы можете использовать ее id как часть запроса.

Чтобы узнать больше, вам нужно будет получить лот более конкретно о том, какую именно проблему вы пытаетесь решить, и масштаб решения, которое вы пытаетесь выполнить.

+0

Ваша концепция «должно иметь» и «может иметь» поисковые термины имеет большое значение для сокращения количества сохраненных поисков, которые должны выполняться против новых документов. Вторая часть вопроса более связана с django - скажем, у вас есть экземпляр модели - как точно будет запускать фильтр/запрос только с одним экземпляром, чтобы определить логическое соответствие? – edub

+0

+1, я думал о решениях для этой проблемы и пришел к такому же решению. Хотя я все еще ищу другие возможные решения, этот дизайн намного лучше, чем через каждый сохраненный запрос, чтобы проверить, совпадает ли он с новой записью. Спасибо за публикацию. –

1

Если вы сохранили тип (ы) объекта (ов), участвующих в каждом сохраненном поиске, как generic relation, вы можете добавить пост-сохранение signal ко всем связанным объектам. Когда срабатывает сигнал, он ищет только те поиски, которые связаны с типом объекта и запускают их. Вероятно, это все равно столкнется с проблемами масштабирования, если у вас есть тонна записи в db и много сохраненных поисков, но это будет простой подход Django.

+0

Думая об этом, если вы сделали это как задачу cron или использовали Celery/аналогично процессу новых элементов за пределами процесса сохранения, вам не придется беспокоиться о масштабировании. – Tom

Смежные вопросы