文章目录
单字段索引
示例文档
假如现在有一个名字为records
的集合,并且单个文档的示例如下
{
"_id": ObjectId("570c04a4ad233577f97dc459"),
"score": 1034,
"location": { state: "NY", city: "New York" }
}
创建一个从小到大排序的索引
db.records.createIndex({score: 1})
这样的话,就会有一个score从小到大排序的索引,接下的查询就会走这个索引
db.records.find( { score: 2 } )
db.records.find( { score: { $gt: 10 } } )
创建一个嵌套字段的内部字段索引
db.records.createIndex({"location.state" : 1})
这样的话,就会有一个嵌套的文档的索引,如下就会走索引
db.records.find( { "location.state": "CA" } )
db.records.find( { "location.city": "Albany", "location.state": "NY" } )
第二个查询的会被优化,调整为
db.records.find( { "location.state": "NY", "location.city": "Albany"} )
创建一个嵌套字段的索引
db.records.createIndex( { location: 1 } )
如下就会走上面的索引
db.records.find( { location: { city: "New York", state: "NY" } } )
组合索引
示例文档
假如现在有一个名字为products
的集合,并且单个文档的示例如下
{
"_id": ObjectId(...),
"item": "Banana",
"category": ["food", "produce", "grocery"],
"location": "4th Street Store",
"stock": 4,
"type": "cases"
}
创建一个简单的组合索引
创建一个item顺序排序,stock逆序排序
db.products.createIndex( { "item": 1, "stock": 1 } )
如下查询便会走上述索引
db.products.find( { item: "Banana" } )
db.products.find( { item: "Banana", stock: { $gt: 5 } } )
把第二个查询反转一个也会使用索引,mongodb会优化一下
排序
在上面我们可以看到我们创建的索引都是有序的。
db.events.find().sort( { username: 1, date: -1 } )
db.events.find().sort( { username: -1, date: 1 } )
那么,如何支持这两种查询的排序,只需要创建一下索引
db.events.createIndex( { "username" : 1, "date" : -1 } )
但是如下查询不被索引支持
db.events.find().sort( { username: 1, date: 1 } )
prefixes
索引prefixes是索引字段的开始子集。
假如有以下复合索引
{ "item": 1, "location": 1, "stock": 1 }
这个prefixes如下
{ "item": 1}
{ "item": 1, "location": 1 }`
那么mongodb会创建如下索引
{ "item": 1}
{ "item": 1, "location": 1 }`
{ "item": 1, "location": 1, "stock": 1 }
但是查询条件不会使用索引
{ "location": 1}
{ "stock": 1}
{ "location": 1, "stock": 1 }
这个和oracle、mysql的做法都类似
多键索引
介绍
多键索引是为了索引数组这种字段,MongoDB
将会为数组的每一个元素创建一个索引,这些索引支持针对数组字段的高效查询,多键索引可以在包含标量值(例如字符串,数字)和嵌套文档的数组上构造。标量值指的是既不是嵌套文档也不是数组的值。
创建一个多键索引
db.coll.createIndex( { <field>: < 1 or -1 > } )
如果索引字段是数组,MongoDB 自动创建一个多键索引, 你不需要明确的指明它。
MongoDB 3.4才开始支持
示例
声明一个集合survey
,并且其定义如下
{ _id: 1, item: "ABC", ratings: [ 2, 5, 9 ] }
为字段ratings
创建一个索引
db.survey.createIndex( { ratings: 1 } )
由于ratings
字段是一个数组,这个字段的索引就是多键索引。这个多键索引包含以下键值
2
5
9
为字段为嵌套文档的数组创建索引
声明一个集合inventory
,并且其定义如下
{
_id: 1,
item: "abc",
stock: [
{ size: "S", color: "red", quantity: 25 },
{ size: "S", color: "blue", quantity: 10 },
{ size: "M", color: "blue", quantity: 50 }
]
}
{
_id: 2,
item: "def",
stock: [
{ size: "S", color: "blue", quantity: 20 },
{ size: "M", color: "blue", quantity: 5 },
{ size: "M", color: "black", quantity: 10 },
{ size: "L", color: "red", quantity: 2 }
]
}
{
_id: 3,
item: "ijk",
stock: [
{ size: "M", color: "blue", quantity: 15 },
{ size: "L", color: "blue", quantity: 100 },
{ size: "L", color: "red", quantity: 25 }
]
}
下面的操作将会为stock.size
和stock.quantity
两个字段创建索引
db.inventory.createIndex( { "stock.size": 1, "stock.quantity": 1 } )
这个复合的索引可以为这两个字段的查询和"stock.size"单字段查询提供支持,
示例如下:
db.inventory.find( { "stock.size": "M" } )
db.inventory.find( { "stock.size": "S", "stock.quantity": { $gt: 20 } } )
这个索引也可以支持查询和排序一起的操作
db.inventory.find( ).sort( { "stock.size": 1, "stock.quantity": 1 } )
db.inventory.find( { "stock.size": "M" } ).sort( { "stock.quantity": 1 } )
小节
索引的原理创建提供功能大同小异,这是很久之前写在笔记上的,今天复习顺便分享一下