2013-10-06 2 views
0

Скажем, у меня есть коллекции документов пользователя, индексированные по электронной почте. Учитывая список адресов электронной почты, мне нужно:MongoDB Учитывая список ключей, получите все соответствующие документы и создайте новые документы для несоответствующих ключей.

1. Get each User doc whose email is in that list 
2. Create a new User doc for each email in the list for which no User exists. 

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

Каков наиболее эффективный способ выполнить обе указанные задачи? Есть ли быстрый способ пакетного ввода новых пользовательских документов из набора уникальных писем?

ответ

0

Я надеялся, что есть какой-то способ получить запрос $ в запросе списка адресов электронной почты, которые не найдены в БД.

Вы можете использовать $nin. К сожалению, $ne и $nincan't make good use of indexes, так что, возможно, не лучший выбор (но, возможно, стоит попробовать).

Лучший подход, вероятно, зависит от вашего «кэш-промахов-курс», но это должно работать, если количество существующих матчей не слишком высока (псевдокод)

var emails; 
var matchingMails = users.find({"email" : {$in : emails}}, {"email":1, "_id":0}); 
var newEmails = emails.subtract(matchingMails); // set difference 
db.batchInsert(createUsersFromEmails(newEmails)); 

т.е.

  1. Найти всех пользователей с соответствующими адресами электронной почты, используя $in. Обязательно возвращайте только поле электронной почты, поэтому query is covered (т. Е. MongoDB просматривает только сами индексы и не нуждается в проверке документов)

  2. Удалить все письма из списка, которые уже находятся в базе данных (простые строковой операции, быстро)

  3. Пакетная вставки вновь созданных пользователей (т.е. создать список или массив пользовательских объектов на стороне клиента и отправить их в БД)

Это ограничивает количество круглых поездок к базе данных. Поскольку запрос конвертируется индексом, он будет очень быстрым, если ваша RAM не будет исчерпана, и индекс больше не вписывается в ОЗУ.

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

Число элементов для запроса $in не должно быть слишком высоким, где-то от 1000 до 10000 как правило.

+0

Удивительный, это путь, по которому я спускался. Как изменится ваш ответ, если я захочу вернуть весь документ для соответствия пользователям? – jcksncllwy

+0

хорошо, нет много. Просто сделайте все данные. Таким образом, запрос не будет покрыт, но если вам нужны данные, вам это нужно. На шаге 2 вы можете действовать по-прежнему, только когда вы выполняете заданный вычитание, вам нужна простая проекция, такая как 'x -> x.email'. – mnemosyn

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