Кэширование массива из БД (MongoDB) в Node.js / Express.js - PullRequest
1 голос
/ 14 июля 2010

Я хотел добавить автозаполнение поиска пользователей (например, Facebook) в свое приложение Rails на Heroku, и я решил написать его в Node.js из-за требований параллелизма. Сначала поиск извлекает список друзей пользователя (из идентификаторов, в который входят все друзья в Твиттере, а не только их друзья на нашем сайте) из Mongo, затем ищет пользователей в этом списке, а затем выполняет другой поиск любых других пользователей, соответствующих запросу, который не были найдены в результатах поиска друзей.

Сначала это было довольно быстро (~ 150 мс), но для пользователей с большим количеством друзей (например, свыше 100) загрузка массива их друзей оказалась огромным узким местом, линейно замедляя поиск до максимума около 1500 мс для пользователя с 1000 друзей (максимальное число поддерживаемых для автозаполнения поиска друзей).

Проблема в том, что я совершенно новичок в Node.js и Express (его Sinatra-подобный веб-фреймворк), и я понятия не имею, как кэшировать массив друзей, поэтому мне нужно загрузить его только один раз (в идеале в память ). В Rails на Heroku я просто загружал массив в Memcache, но я даже не уверен, как настроить Memcache в Node / Express, не говоря уже о том, поддерживается ли он в Heroku.

Есть идеи?

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

Ответы [ 3 ]

8 голосов
/ 15 августа 2010

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

Самое лучшее в базах данных - то, что они могут выполнить эту фильтрацию для вас и быстро. И это должно выходить далеко за рамки других решений. Доверьтесь базе данных, весь смысл mongodb в том, что запрос должен быть невероятно быстрым и близким к скорости memcache. Вам просто нужно задать правильный вопрос. И я полагаю, что вы можете сильно ударить по базе данных, но убедитесь, что запрашиваете только точное количество совпадений, которые вы намереваетесь использовать.

Чтобы соответствовать Джону Сми ... Может быть, что-то вроде этого (я просто придумал это, чтобы показать идею):

friendIdList // Предполагается, что это простой массив идентификаторов из вашего приложения

var matchFriends = db.people.find ({person_id: {$ in: friendIdList}, имя: / john smi. * / I}) .sort ({name: 1}) .limit (10);

См. Документы mongodb по запросам регулярных выражений

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

6 голосов
/ 15 июля 2010

Я очень мало знаю о Node.js или Express.Тем не менее, я могу сказать вам, что вы, вероятно, хотите сделать это на стороне клиента.( т.е.: cookie список друзей на клиенте и использование javascript для поиска )

Если вы посмотрите на реализацию FB, это то, что они делают (по крайней мере, несколько месяцев назад).

0 голосов
/ 16 июня 2011

Я бы посоветовал, если вы не собираетесь предварительно загружать все имена на стороне клиента, тогда вам лучше будет выполнить поиск после ввода первого символа. Это сократит количество имен, которые необходимо найти, до доли, а затем отправит этот запрос в БД. Затем вы можете вернуть эти результаты в алфавитном порядке, как только вы наберете больше символов, вы сможете фильтровать их без сортировки. Каждый запрос должен соответствовать цели 150 мс, если у пользователя нет тысяч друзей по имени «Дэвид Смит».

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