Mongodb 在Mongo中高效索引列表的最佳方法
我有一个文档集合,可以是这样的(选项a): 或类似于此(选项B): 问题是:哪一种查询更有效,例如:获取“我的列表”中id为“B”的所有文档? 另外,为了更好的选择,您如何告诉Mongo创建相关索引?肯定是第一个。 MongoDB使用多键索引来索引存储在数组中的内容。如果索引包含数组值的字段,MongoDB将为数组的每个元素创建单独的索引项。这些多键索引允许查询通过匹配数组的一个或多个元素来选择包含数组的文档。如果索引字段包含数组值,MongoDB自动确定是否创建多键索引;您不需要显式指定多键类型 第二个选项是Mongodb 在Mongo中高效索引列表的最佳方法,mongodb,indexing,Mongodb,Indexing,我有一个文档集合,可以是这样的(选项a): 或类似于此(选项B): 问题是:哪一种查询更有效,例如:获取“我的列表”中id为“B”的所有文档? 另外,为了更好的选择,您如何告诉Mongo创建相关索引?肯定是第一个。 MongoDB使用多键索引来索引存储在数组中的内容。如果索引包含数组值的字段,MongoDB将为数组的每个元素创建单独的索引项。这些多键索引允许查询通过匹配数组的一个或多个元素来选择包含数组的文档。如果索引字段包含数组值,MongoDB自动确定是否创建多键索引;您不需要显式指定多键类
对象
类型。您需要创建单个字段
或复合索引
来使用索引
将数组转换为键:值存储
MongoDB允许您在聚合期间将多键索引数组
转换为键:值
存储,即:
db.collection.aggregate([
{
$match: { "my_list.id" : "A" }
},
{
$project: {
my_list: {
$arrayToObject: {
$map: {
input: "$my_list",
in: {
k: "$$this.id",
v: "$$this.other_data"
}
}
}
}
}
}
])
如果我们看一看命令,MongoDB使用索引来高效执行查询
{
"stages" : [
{
"$cursor" : {
"query" : {
"my_list.id" : "A"
},
"fields" : {
"my_list" : 1,
"_id" : 1
},
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.collection",
"indexFilterSet" : false,
"parsedQuery" : {
"my_list.id" : {
"$eq" : "A"
}
},
"queryHash" : "599B2BF4",
"planCacheKey" : "48B2FCB0",
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"my_list.id" : 1.0
},
"indexName" : "my_list.id_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"my_list.id" : [
"my_list"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"my_list.id" : [
"[\"A\", \"A\"]"
]
}
}
},
"rejectedPlans" : []
}
}
},
{
"$project" : {
"_id" : true,
"my_list" : {
"$arrayToObject" : [
{
"$map" : {
"input" : "$my_list",
"as" : "this",
"in" : {
"k" : "$$this.id",
"v" : "$$this.other_data"
}
}
}
]
}
}
}
],
"ok" : 1.0
}
也许这与此无关,但我更喜欢选项B,因为它看起来更简单,有助于避免数据中的重复,但引擎使用“$exists”运行查询可能要困难得多?而且,不用说,“我的列表”可能有许多记录,而且集合中可能有许多文档。技术上,
my_list
不是一个列表(:我使用“list”(据我所知,它在Mongo中并不真正意味着什么)是为了避免给人留下这样的印象,即我需要用数组或对象来实现它。my_list
中有多少项(id)?您是否在查询字段“B”的存在或者存储在其中的值(456
)。例如,if(B==456)
,或者if(B)
?
{
"my_list": [
{ "id": "A", "other_data": 123 },
{ "id": "B", "other_data": 456 },
{ "id": "C", "other_data": 789 },
]
}
db.collection.aggregate([
{
$match: { "my_list.id" : "A" }
},
{
$project: {
my_list: {
$arrayToObject: {
$map: {
input: "$my_list",
in: {
k: "$$this.id",
v: "$$this.other_data"
}
}
}
}
}
}
])
{
"stages" : [
{
"$cursor" : {
"query" : {
"my_list.id" : "A"
},
"fields" : {
"my_list" : 1,
"_id" : 1
},
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.collection",
"indexFilterSet" : false,
"parsedQuery" : {
"my_list.id" : {
"$eq" : "A"
}
},
"queryHash" : "599B2BF4",
"planCacheKey" : "48B2FCB0",
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"my_list.id" : 1.0
},
"indexName" : "my_list.id_1",
"isMultiKey" : true,
"multiKeyPaths" : {
"my_list.id" : [
"my_list"
]
},
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"my_list.id" : [
"[\"A\", \"A\"]"
]
}
}
},
"rejectedPlans" : []
}
}
},
{
"$project" : {
"_id" : true,
"my_list" : {
"$arrayToObject" : [
{
"$map" : {
"input" : "$my_list",
"as" : "this",
"in" : {
"k" : "$$this.id",
"v" : "$$this.other_data"
}
}
}
]
}
}
}
],
"ok" : 1.0
}