我对mongodb很新,我一直在努力找出我需要做些什么来改进这个查询,我似乎无法找到任何修复它的东西。我已经尝试在该字段上添加索引,但在大约一百五十万用户的数据集上通过电子邮件地址查找用户仍需要大约24秒。查询只是:
UserModel.findOne({
'emails.address': emailAddr
}, {
_id: true,
account_status: true,
local_auth: true,
personas: {$elemMatch: {is_default: true}}
}, function (err, user) { });
_id字段有索引,emails.address字段有另一个索引。这是分析器的输出:
{ "op" : "query", "ns" : "dbname", "query" : { "emails.address" : "test@ggsfg.com" }, "ntoreturn" : 1, "ntoskip" : 0, "nscanned" : 1560155, "keyUpdates" : 0, "numYield" : 23, "lockStats" : { "timeLockedMicros" : { "r" : NumberLong(47843876), "w" : NumberLong(0) }, "timeAcquiringMicros" : { "r" : NumberLong(23600947), "w" : NumberLong(7) } }, "nreturned" : 0, "responseLength" : 20, "millis" : 24252, "ts" : ISODate("2014-01-26T17:47:00.658Z"), "client" : "", "allUsers" : [ ], "user" : "" }
mongoose模式看起来像(它有一个_id对象字段,并且在模式的根目录上有自己的索引,并且电子邮件集合中还有另一个_id):
{
... other fields ...
emails: [
{
address: {
type: String,
match: /^(?:[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+\.)*[\w\!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~]+@(?:(?:(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!\.)){0,61}[a-zA-Z0-9]?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-](?!$)){0,61}[a-zA-Z0-9]?)|(?:\[(?:(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\.){3}(?:[01]?\d{1,2}|2[0-4]\d|25[0-5])\]))$/,
index: true
},
is_default: {
type: Boolean,
require: true,
'default': false
},
added_at: {
type: Date,
'default': Date.now
},
verified_at: {
type: Date
},
verification_key: {
type: String
}
}
],
... other fields ...
}
如果有人能指出我需要做些什么才能让这个查询快速运行,我将非常感激。
编辑: 好吧,这是我构建查询的方式导致索引字段不被使用。我现在把它改成了它,它完美无缺
UserModel.findOne({
emails: {
"$elemMatch": {
address: emailAddr
}
}