0

假设我有一组按电子邮件地址索引的用户文档。给定电子邮件地址列表,我需要:

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 查询返回数据库中未找到的电子邮件列表。然后我可以有效地插入新文档。否则,我必须遍历文档以查找未收到的电子邮件。

完成上述两项任务的最有效方法是什么?有没有一种快速的方法可以从一组独特的电子邮件中批量插入新的用户文档?

4

1 回答 1

0

我希望有某种方法可以让 $in 查询返回数据库中未找到的电子邮件列表。

你可以使用$nin. 不幸的是,$ne并且$nin 不能很好地利用索引,所以这可能不是你最好的选择(但也许值得一试)。

最好的方法可能取决于您的“缓存未命中率”,但如果现有匹配的数量不太高(伪代码),这应该可以工作

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

IE

  1. 使用 查找具有匹配电子邮件地址的所有用户$in。确保只返回电子邮件字段本身,以便覆盖查询(即 MongoDB 只查看索引本身,而不必扫描文档)

  2. 从列表中删除所有已经在数据库中的电子邮件(简单的字符串操作,快速)

  3. 批量插入新创建的用户(即在客户端创建一个用户对象列表或数组并将它们发送到数据库)

这限制了到数据库的往返次数。由于查询是索引转换的,因此它将非常非常快,除非您的 RAM 已用尽并且索引不再适合 RAM。

明智的做法是在电子邮件地址上使用唯一索引并允许批量插入完成,即使个别插入失败,以防有人在其间注册或有另一个线程运行此代码。

查询的元素数量$in不应太高,根据经验,在 1,000 到 10,000 之间。

于 2013-10-07T08:59:15.633 回答