Отфильтруйте список элементов для членства в MongoDB

#python #mongodb #pymongo

#python #mongodb #pymongo

Вопрос:

Итак, я использую Python Pymongo (хотя этот вопрос может быть применим к любому языку), и у меня есть список электронных писем на Python, emails=['email1@example.com','email2@example.com',...] и у меня есть коллекция в MongoDB с кучей документов. Каждый документ в MongoDB имеет email поле. Каков наиболее эффективный (и элегантный) способ фильтрации списка Python, поэтому, когда я закончу, он будет содержать только электронные письма, которые присутствуют в одном из email полей в MongoDB?

ВВОД: emails=['email1@example.com','email2@example.com',...]

ВЫВОД: filteredEmails=[ <sublist of 'emails' with only elements present in MongoDB

Ответ №1:

Я думаю, это то, что вы ищете:

 > db.people.insert({name:"Fred",email:"fred@email.com"})
> db.people.insert({name:"Derf",email:"derf@email.com"})
> db.people.insert({name:"Bob",email:"bob@email.com"})
>
>
> emails = ["derf@email.com", "bob@email.com"]
[ "derf@email.com", "bob@email.com" ]
> db.people.find({email:{$in: emails}})
{ "_id" : ObjectId("53a1f4b44336adbf6340356a"), "name" : "Derf", "email" : "derf@email.com" }
{ "_id" : ObjectId("53a1f4bb4336adbf6340356b"), "name" : "Bob", "email" : "bob@email.com" }
 

Просто используйте .find() с $in оператором, чтобы найти все документы, адрес электронной почты которых находится в списке адресов электронной почты.

Комментарии:

1. Насколько эффективна эта операция? Увеличивается ли временная сложность с длиной списка адресов электронной почты? Что, если список действительно длинный?

Ответ №2:

Предполагая email , что поле проиндексировано, просто найдите каждое значение. Это должно быть достаточно быстро.

 common_emails = [ email for email in emails if coll.find_one({ 'email': email }) ]
 

Если коллекция невелика или вы не хотите индексировать email поле, выполнение пересечения в памяти окажется быстрее:

 db_emails = [ doc['email'] for doc in coll.find({}, projection = {'email':1, '_id':0}) if doc ]
common_emails = set(emails) amp; set(db_emails)