我们目前正在将一组权限作为集合上的Map进行管理。每一组权限都以用户id作为键进行归档。由于某些原因,该键当前是BSONObjectID的字符串化版本。
我想在键上维护一个索引,这样我就可以查找相关的权限集,也可以找到那些特定用户权限存在的文档。
例子:
{"_id" : {"$oid" : "xxxxxx"},
"irrelevantData" : "Document1 data...",
"permissions" : {
"key1" : {"perm1" : true, "perm2: false},
"key3" : {"perm1" : true, "perm2: false}
}
{"_id" : {"$oid" : "yyyyyy"},
"irrelevantData" : "Document2 data...",
"permissions" : {
"key1" : {"perm1" : false, "perm2: true},
"key2" : {"perm1" : true, "perm2: false}
}
在上面的例子中,我希望我的索引能够只选择"key2"在权限中存在的文档。
模型如下:
case class relevantCollection(
_id: BSONObjectID,
irrelevantData: String,
permissions: Option[Map[String, Map[String, Boolean]]]
)
如何在键上创建索引而不是值上创建索引?是否有任何性能问题,关于这个键是字符串vs. BSONObjectID?
您可以使用稀疏索引满足此需求。索引将只包含具有"权限"的文档。
db.permissions.createIndex({"permissions.key2" : 1}, {sparse: true })
可以使用下面的查询来检查索引是否正在被使用。
db.getCollection('permissions').find({"permissions.key2" : {
"perm1" : true,
"perm2" : false
}}).explain();
在输出的JSON中,检查获胜计划是否有"IXSCAN"。
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"permissions.key2" : 1
},
"indexName" : "permissions.key2_1",
"isMultiKey" : false,
"isUnique" : false,
"isSparse" : true,
"isPartial" : false,
"indexVersion" : 1,
"direction" : "forward",
"indexBounds" : {
"permissions.key2" : [
"[{ perm1: true, perm2: false }, { perm1: true, perm2: false }]"
]
}
}
}
同样,如果运行下面的查询,获胜的计划将显示"COLLSCAN"。
db.getCollection('permissions').find({"permissions.key1" : {
"perm1" : false,
"perm2" : true
}}).explain()
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"permissions.key1" : {
"$eq" : {
"perm1" : false,
"perm2" : true
}
}
},
"direction" : "forward"
}