MongoDB 聚合索引是一种包含多个字段的索引,它可以提高查询效率,特别是在需要对多个字段进行查询或者聚合操作时。以下是 MongoDB 官方文档中关于聚合索引的详细说明和示例:
定义聚合索引
在 MongoDB 中,可以通过以下语法定义聚合索引:
代码语言:javascript复制db.collection.createIndex({ field1: 1, field2: -1, ... })
其中,field1
、field2
等为字段名称,1
和 -1
表示该字段的索引方向,1
表示升序,-1
表示降序。可以定义多个字段,MongoDB 会按照字段的先后顺序创建索引。
例如,可以创建一个基于 name
和 age
字段的聚合索引:
db.users.createIndex({ name: 1, age: -1 })
使用聚合索引进行查询
使用聚合索引进行查询时,需要指定查询条件并使用 explain()
命令查看查询执行计划,以确认是否使用了聚合索引。
例如,可以使用以下查询语句查询 name
为 "Alice"、age
大于等于 20 的用户,并查看执行计划:
db.users.find({ name: "Alice", age: { $gte: 20 } }).explain()
执行计划中的 winningPlan
字段会显示是否使用了聚合索引。
优化聚合索引
为了优化聚合索引的效率,可以采取以下措施:
- 选择正确的索引字段:根据实际查询场景选择索引字段,避免创建过多或不必要的索引。
- 避免使用过多的索引字段:每个索引字段都需要占用额外的存储空间和处理时间,因此应该避免创建过多的索引字段。
- 定期重新生成索引:当数据量增加或者索引使用频率发生变化时,应该及时重新生成索引,以确保索引的效率。
以下是一个使用聚合索引的示例:
代码语言:javascript复制// 创建聚合索引
db.users.createIndex({ name: 1, age: -1 })
// 插入数据
db.users.insertMany([
{ name: "Alice", age: 25, gender: "female" },
{ name: "Bob", age: 30, gender: "male" },
{ name: "Charlie", age: 25, gender: "male" },
{ name: "David", age: 20, gender: "male" },
{ name: "Eve", age: 30, gender: "female" }
])
// 查询年龄大于等于 25 的女性用户,使用聚合索引
db.users.find({ age: { $gte: 25 }, gender: "female" }).explain()
执行上述查询后,执行计划中的 winningPlan
字段会显示使用了聚合索引:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.users",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{ "age" : { "$gte" : 25 } },
{ "gender" : { "$eq" : "female" } }
]
},
"winningPlan" : {
"stage" : "FETCH",
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : { "age" : 1, "name" : 1 },
"indexName" : "name_1_age_-1",
"isMultiKey" : false,
"multiKeyPaths" : { "age" : [], "name" : [] },
"isUnique" : false,
"isSparse" : false,
"isPartial" : false,
"indexVersion" : 2,
"direction" : "forward",
"indexBounds" : {
"age" : [ "25", { "$maxValue" : 1 } ],
"name" : [ { "$minValue" : 1 }, { "$maxValue" : 1 } ]
}
}
},
"rejectedPlans" : []
},
"serverInfo" : {
"host" : "localhost",
"port" : 27017,
"version" : "4.4.0",
"gitVersion" : "563487e100c4215e2dce98d0af2a6a5a2d67c5cf"
},
"ok" : 1
}
可以看到,执行计划中使用了 name_1_age_-1
索引,表示聚合索引生效。