mongodb - MongoDB:查询多个字段和索引
问题描述
我通过猫鼬使用 MongoDB。
当您使用非索引字段查询索引字段时会发生什么?请参阅下面的代码。
// For example MyModel.find({ _id: '123', name: 'Jina'});
MongoDB 是否进行集合扫描或索引是否有助于提高查询效率?查询与仅使用该
_id
字段有什么不同吗?如果 MongoDB 在您查询非索引字段时进行集合扫描。如果集合扫描完全一样,查询多个非索引字段是否会加快查询速度?假设我查询五个非索引字段而不是两个(都返回相同的文档)。两个查询是否执行相同的集合扫描?
解决方案
要了解 mongo 查询中发生的事情,您可以使用explain
. 例如,考虑以下查询:
db.getCollection('users').find({"name":"ana"})
查询非索引字段。您可以在此查询上使用说明,如下所示:
db.getCollection('users').find({"name":"ana"}).explain("executionStats")
部分结果是:
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "anonymous-chat.users",
"indexFilterSet" : false,
"parsedQuery" : {
"name" : {
"$eq" : "ana"
}
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"name" : {
"$eq" : "ana"
}
},
"direction" : "forward"
},
"rejectedPlans" : []
},
如您所见,这里我们有COLLSCAN
一个集合扫描。现在我们只需查询 _id 并查看结果:
db.getCollection('users').find({"_id":ObjectId("5ee9b6c125b9a9a426d9965f")}).explain("executionStats")
结果如下:
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "anonymous-chat.users",
"indexFilterSet" : false,
"parsedQuery" : {
"_id" : {
"$eq" : ObjectId("5ee9b6c125b9a9a426d9965f")
}
},
"winningPlan" : {
"stage" : "IDHACK"
},
"rejectedPlans" : []
},
正如我们所看到的,我们IDHACK
在查询时只有_id。
现在我们结合 _id 和 name:
db.getCollection('users').find({"_id":ObjectId("5ee9b6c125b9a9a426d9965f"), "name":"ana"}).explain("executionStats")
这是结果:
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "anonymous-chat.users",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"_id" : {
"$eq" : ObjectId("5ee9b6c125b9a9a426d9965f")
}
},
{
"name" : {
"$eq" : "ana"
}
}
]
},
"winningPlan" : {
"stage" : "FETCH",
"filter" : {
"name" : {
"$eq" : "ana"
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"_id" : 1
},
"indexName" : "_id_",
"isMultiKey" : false,
"multiKeyPaths" : {
"_id" : []
},
"isUnique" : true,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"_id" : [
"[ObjectId('5ee9b6c125b9a9a426d9965f'), ObjectId('5ee9b6c125b9a9a426d9965f')]"
]
}
}
},
"rejectedPlans" : []
},
正如我们所见,索引有助于提高查询性能,因为我们有两个阶段,一个IXSCAN
(索引扫描)和一个FETCH
过滤最后阶段文档的阶段。
现在让我们查询多个非索引字段以了解您的第二个问题:
db.getCollection('users').find({"name":"ana", "appId":1}).explain("executionStats")
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "anonymous-chat.users",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"appId" : {
"$eq" : 1.0
}
},
{
"name" : {
"$eq" : "ana"
}
}
]
},
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"$and" : [
{
"appId" : {
"$eq" : 1.0
}
},
{
"name" : {
"$eq" : "ana"
}
}
]
},
"direction" : "forward"
},
"rejectedPlans" : []
},
正如我们在上面看到的,对于多个字段只有一个集合扫描。
推荐阅读
- vba - MS Project VBA - 当过滤器不返回任何内容时如何避免错误
- html - HTTP 错误 405
- python - AttributeError:“Nonetype”对象在 discord.py 中没有属性“角色”
- javascript - nodemailer不发送电子邮件node.js
- html - 网站上带有照片边距问题的 html 表格
- node.js - 将标头发送到客户端后无法设置标头-Nodejs + AWS-S3 getObject
- ios - 网络连接迅速丢失
- label - 标签可以默认隐藏,但在选择节点时显示?
- javascript - Kaboom - 是否有等效的接地()属性用于触摸墙壁?
- javascript - 如何在 RxJS 中延迟重试 Observable 内部管道?