一个替代方案是通过在模式中引入另一个字段来修改数据结构,该字段仅包含电子邮件地址的域值。可以使用
Bulk API操作进行批量更新,这些操作提供更好的写入响应,即有关更新期间实际发生情况的有用信息。
var bulk = db.my_emails.initializeUnorderedBulkOp(),
count = 0;
db.my_emails.find().forEach(function(doc) {
var domain = doc.email.replace(/.*@/, ""),
update = { domain: domain };
bulk.find({ "_id": doc._id }).updateOne({
"$set": update
})
count++;
if (count % 1000 == 0) {
bulk.execute();
bulk = db.my_emails.initializeUnorderedBulkOp();
}
})
if (count % 1000 != 0) { bulk.execute(); }
样本的批量更新响应:
BulkWriteResult({
"writeErrors" : [ ],
"writeConcernErrors" : [ ],
"nInserted" : 0,
"nUpserted" : 0,
"nMatched" : 3,
"nModified" : 3,
"nRemoved" : 0,
"upserted" : [ ]
})
在此更新后,对集合
db.my_emails.find().pretty()
的查询将产生以下结果:
{
"_id" : ObjectId("561618af645a64b1a70af2c5"),
"email" : "russel@gmail.com",
"domain" : "gmail.com"
}
{
"_id" : ObjectId("561618af645a64b1a70af2c6"),
"email" : "mickey@yahoo.com",
"domain" : "yahoo.com"
}
{
"_id" : ObjectId("561618af645a64b1a70af2c7"),
"email" : "john@yahoo.com",
"domain" : "yahoo.com"
}
现在,拥有域字段将使
聚合框架更容易通过
$sum
操作符在
$group
管道中返回主机计数。以下管道操作将返回所需的结果:
db.my_emails.aggregate([
{
"$group": {
"_id": "$domain",
"count": { "$sum": 1 }
}
}
])
输出:
{ "_id" : "yahoo.com", "count" : 2 }
{ "_id" : "gmail.com", "count" : 1 }