说我有一组用电子邮件地址索引的用户文档。给出一个电子邮件地址列表,我需要:
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.
我可以使用$ in查询轻松解决第一个问题,但我希望有一些方法可以让$ in查询返回数据库中找不到的电子邮件列表。然后我可以有效地插入新的文档。否则,我必须遍历文档以查找未接收的电子邮件。
完成上述两项任务的最有效方法是什么?有没有快速的方法从一组独特的电子邮件中批量插入新的用户文档?
答案 0 :(得分:0)
我希望有一些方法可以让$ in查询返回数据库中找不到的电子邮件列表。
您可以使用$nin
。很遗憾,$ne
和$nin
can't make good use of indexes,这可能不是您最好的选择(但也许值得一试)。
最好的方法可能取决于你的'cache-miss-rate',但是如果现有匹配的数量不是太高(伪代码),这应该有效
var emails;
var matchingMails = users.find({"email" : {$in : emails}}, {"email":1, "_id":0});
var newEmails = emails.subtract(matchingMails); // set difference
db.batchInsert(createUsersFromEmails(newEmails));
即
使用$in
查找具有匹配电子邮件地址的所有用户。确保只返回电子邮件字段本身,以便query is covered(即MongoDB只查看索引本身而不必扫描文档)
从列表中删除数据库中已有的所有电子邮件(快速简单字符串操作)
批量插入新创建的用户(即创建客户端用户对象的列表或数组并将其发送到数据库)
这限制了到数据库的往返次数。由于查询是索引控制的,除非你的RAM耗尽且索引不再适合RAM,否则它将非常非常快。
明智的做法是在电子邮件地址上使用唯一索引,并允许批量插入完成,即使单个插入失败,以防有人在其间注册,或者有另一个线程运行此代码。
$in
查询的元素数量不应太高,根据经验,大概在1,000到10,000之间。