2008-11-24 7 views
3

Я разрабатываю своего рода персонализированную поисковую систему в Ruby on Rails, и в настоящее время я пытаюсь найти лучший способ сортировки результатов в зависимости от записи пользователя в реальном времени.RT параллельная обработка в Rails

Пример: элементы, которые можно найти, могут иметь теги (отдельные объекты с идентификаторами), например item имеет теги = [1, 5, 10, 23, 45].

Пользователь, с другой стороны, может помечать некоторые теги с особым интересом, поэтому скажите, что пользователь имеет теги = [5, 23].

Оценка, используемая для сортировки результатов, должна учитывать количество тегов элемента, которые «смотрят» на пользователя. Например, оценка предмета будет составлять 50% на основе атрибутов предмета и 50% на ранжирование в зависимости от пользователя (количество тегов смотрится).

Одна из идей заключалась в том, чтобы вставить это в функцию сортировки в информационно-поисковой системе. Но в Sphinx, который я, вероятно, буду использовать, было бы очень неудобно реализовать (когда вектор пользователя большой). Я не знаю о Lucene/solr, но у них, похоже, нет расширенных возможностей нетекстового поиска, которые мне нужны в любом случае (расстояние, дата, время и т. Д.)

Другой вариант - получить посреднический набор из ИК-системы, а затем обрабатывать ее на уровне приложения. Однако я уверен, что обработка 100-1000 записей последовательно, а затем их сортировка в Rails будет очень медленной.

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

Я читал о нескольких реализациях с уменьшением масштаба, как универсальных, так и хаотических, таких как skynet и т. Д., Но они лучше всего подходят для больших пакетных заданий, а не для обработки в реальном времени (если я не ошибаюсь?).

Есть ли встроенная память, легкая реализация MR, которую я мог бы использовать для этого? Или, может быть, у вас есть другие идеи, как с этим справиться?

(sidenote: Я считаю, что эта настройка похожа на то, как работают новости Google, из того, что я понимаю из статьи «Персонализация новостей Google: масштабируемая онлайн-совместная фильтрация». Они соответствуют в реальном времени множеству рассказов кандидатов с набором кластеров к которому пользователь относится (предварительно рассчитанный ранее) для сортировки истории в индивидуальном порядке)

ответ

1

Map/Reduce отлично подходит для такого рода вещей, но вы можете справиться с ним в SQL, используя промежуточную таблицу.

Предположительно, у вас уже есть таблицы, как это:

 
users (id, ...) 
items (id, ...) 
tags (id, ...) 
users_tags (user_id, tag_id) 
items_tags (item_id, tag_id) 

Итак, почему не вы также поддерживать таблицу, как это:

users_items_tags (user_id, item_id, tag_id)

, где каждая строка означает «этот пользователь и это item share this tag ".

Затем ваш поисковый запрос что-то вроде этого:

 
    select item_id, count(tag_id) as score 
    from users_items_tags 
    where user_id = <USER_ID> 
group by item_id 
order by score desc 

Когда пользователь добавляет тег, users_items_tags обновляется следующим образом:

 
insert into users_items_tags (user_id, item_id, tag_id) 
    select <USER_ID>, item_id, <TAG_ID> 
     from items_tags 
     where tag_id = <TAG_ID> 

и также при добавлении тега к элементу ,Когда тег удален, просто удалите тег и пользователь/элемент.

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

+0

Thx, это одна из возможностей, однако, поскольку пользователю вполне может быть предложено 20-50% рекомендованных ему предметов, а количество меток преднамеренно ограничено, это приведет к довольно большому количеству данных. – Otigo 2008-12-09 20:49:19