mongodb - Mongo Distinct Index for Dot Notated
问题描述
我有一个托管在 Atlas 上的 mongodb v4.2.2。有一个集合
objects
和两个字段:metadata
作为对象数组,每个对象都有一个字段key
和第二个字段,名为model
. 将复合索引添加model->metadata.key
为常规索引。从控制台运行 db 命令db.objects.explain('executionStats').distinct('metadata.key', {model: ObjectId('5e18aff58a5aaffdc3d6f26d')})
时,它不使用我的model->metadata.key
索引,也不使用 DISTINCT_SCAN。但是,如果我将数据移动到另一个集合,可以说
objectKeys
有两个字段,例如key
,model
并再次添加常规复合索引model->key
并运行命令db.objectKeys.explain('executionStats').distinct('key', {model: ObjectId('5e18aff58a5aaffdc3d6f26d')})
,它成功应用 DISTINCT_SCAN 并使用索引。- 问题。如何强制 MongoDB 在不同操作期间使用点标记字段的索引?
更新详情:
1.
db.objects.getIndexes();
{
"v" : 2,
"key" : {
"model" : 1,
"metadata.key" : 1,
"metadata.value" : 1
},
"name" : "model_1_metadata.key_1_metadata.value_1",
"ns" : "my_db.objects",
"background" : true
}
db.objects.explain('executionStats').distinct('metadata.key', {model: ObjectId('5e18aff58a5aaffdc3d6f26d')})
"executionStages" : {
"stage" : "FETCH",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 1,
"advanced" : 0,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"docsExamined" : 0,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 1,
"advanced" : 0,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"keyPattern" : {
"model" : 1,
"metadata.key" : 1,
"metadata.value" : 1
},
"indexName" : "model_1_metadata.key_1_metadata.value_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"model" : [ ],
"metadata.key" : [
"metadata"
],
"metadata.value" : [
"metadata"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"model" : [
"[ObjectId('5e18aff58a5aaffdc3d6f26d'), ObjectId('5e18aff58a5aaffdc3d6f26d')]"
],
"metadata.key" : [
"[MinKey, MaxKey]"
],
"metadata.value" : [
"[MinKey, MaxKey]"
]
},
"keysExamined" : 0,
"seeks" : 1,
"dupsTested" : 0,
"dupsDropped" : 0
}
}
2.
db.object_keys.getIndexes();
{
"v" : 2,
"key" : {
"models" : 1,
"key" : 1
},
"name" : "models_1_key_1",
"ns" : "my_db.object_keys",
"background" : true
},
db.object_keys.explain('executionStats').distinct('key', {models: ObjectId('5e18aff58a5aaffdc3d6f26d')})
"executionStages" : {
"stage" : "PROJECTION_COVERED",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 1,
"advanced" : 0,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"transformBy" : {
"_id" : 0,
"key" : 1
},
"inputStage" : {
"stage" : "DISTINCT_SCAN",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 1,
"advanced" : 0,
"needTime" : 0,
"needYield" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"keyPattern" : {
"models" : 1,
"key" : 1
},
"indexName" : "models_1_key_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"models" : [
"models"
],
"key" : [ ]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"models" : [
"[ObjectId('5e18aff58a5aaffdc3d6f26d'), ObjectId('5e18aff58a5aaffdc3d6f26d')]"
],
"key" : [
"[MinKey, MaxKey]"
]
},
"keysExamined" : 0
}
}
因此,您可以在第一种情况下看到它使用 IXSCAN 表示索引扫描,而在第二种情况下,它使用 DISTINCT_SCAN 被认为更快。不同之处在于,在第一种情况下,该metadata
字段是对象数组,而在第二种情况下,该字段key
是字符串
解决方案
推荐阅读
- ipad - Ghidra 在任何事情上;可能吗?
- java - 从 IP 查找主机名 - 反向 DNS - android
- haskell - 无法将类型“[]”与“IO”匹配预期:IO (IO ()) 实际:[IO ()]
- java - 在非根路由上获得响应 404
- flutter - onTap 方法无法更改堆栈内容器的颜色和动画容器内卡片颜色的不透明度
- html - 有没有办法将 json 数据加载到 html 表中?
- matlab - 在matlab中求解方程
- javascript - 在Slate.js编辑器中编辑的数据在data based中保存为[Object],[Object]。如何使这个Object成为有意义的内容?
- java - 以下代码中方括号后的“+”号有什么用?
- javascript - RegExpExecArray.groups == 在角度库中调用时未定义