MongoDB 索引建立机制

单一字段索引

MongoDB对于collection中的任意字段(field)提供了完整的索引支持,在默认情况下,所有collection中的_id 均建立了索引,并且应用和用户也可以增加额外的索引来支持重要的查询和操作。

以下面的代码为例

{ "_id" : ObjectId(...),
  "name" : "Alice",
  "age" : 27
}

简单的来说,我们如果想给下面的document增加索引,即

db.friends.createIndex( { "name" : 1 } )

内含字段索引

我们可以给内含document的字段添加索引。观察如下数据结构,

{"_id": ObjectId(...),
 "name": "John Doe",
 "address": {
        "street": "Main",
        "zipcode": "53511",
        "state": "WI"
        }
}

我们可以将street,zipcode等看作是一种二维数据结构。即他们是address对象的属性,建立索引也非常简单,访问对象中的属性即可,如下:

db.people.createIndex( { "address.zipcode": 1 } )

内含document索引

我们可以将内含document视作复杂数据类型,当然也可以在此document上建立索引,数据结构如下:

{
  _id: ObjectId(...),
  metro: {
           city: "New York",
           state: "NY"
         },
  name: "Giant Factory"
}

metro字段为内含document,包括了内含字段city和state,我们可以在metro字段直接建立索引,如下:

db.factories.createIndex( { metro: 1 } )

下面的查询利用该字段的索引,精确匹配到如上数据,

db.factories.find( { metro: { city: "New York", state: "NY" } } )

然而,下面的例子却不能匹配到上面的结果。

db.factories.find( { metro: { state: "NY", city: "New York" } } )

组合索引

MongoDB 支持组合索引,一个单一的索引可以绑定多个fields。
mongodb组合索引

注:任何一个组合索引最多可以绑定31个fields
上图中,先按升序建立userid索引,再按降序建立score索引。

例1,

{
 "_id": ObjectId(...),
 "item": "Banana",
 "category": ["food", "produce", "grocery"],
 "location": "4th Street Store",
 "stock": 4,
 "type": "cases",
 "arrival": Date(...)
}

如果我们查询item(field) 或者查询item和stock(field),我们可以定义如下的组合索引来加速我们的查询。

db.products.createIndex( { "item": 1, "stock": 1 } )

例2,
我们建立如下查询:

db.events.find().sort( { username: 1, date: -1 } )
db.events.find().sort( { username: -1, date: 1 } )

上面两种排序查询:

  1. username升序,date降序
  2. username降序,date升序

可以通过建立如下索引来加速查询

db.events.createIndex( { "username" : 1, "date" : -1 } )

然而,上述先升序再降序索引并不支持username,date全部按升序或降序查询,如下

db.events.find().sort( { username: 1, date: 1 } )

索引前缀

索引前缀可以看作是索引字段的向前包含的子集。例如,我们建立如下索引:

{ "item": 1, "location": 1, "stock": 1 }

这样的索引可以有一下的索引前缀。

  • { item: 1 }
  • { item: 1, location: 1 }

对于上述的组合索引,MongoDB能够在索引前缀的基础上建立索引来支持查询,MongoDB能够对如下字段使用索引进行查询。

  • item 字段
  • item和location 字段
  • item, location和stock 字段

有item字段作为前缀,MongoDB也能够使用上述建立的索引来支持基于item和stock字段的查询。但是,这样做的查询效率不及仅对item和stock建立的索引。

然而,MongoDB不能使用上述索引来建立除了item字段之外的查询(不满足索引前缀的要求)

  • location 字段
  • stock 字段
  • location 和 stock 字段

多键值索引

给一个含有数组属性的字段建立索引,MongoDB能够为数组中每一个元素建立索引关键字。多键值索引能够对数组字段进行高效的查询,如下图。
多键值索引
上图中,为addr的zip元素建立了索引。

如果任何索引字段是数组类型,那么MongoDB自动建立一个多键值索引,你不需要显式指明多键值的类型。

限制

在一个建立索引的document中,只能包含一个类型为数组的索引字段.
有如下记录,

{ _id: 1, a: [ 1, 2 ], b: [ 1, 2 ], category: "AB - both arrays" }

因为a和b 字段均为数组类型,所以我们不能建立{ a: 1, b: 1 }的组合索引。
但如果collection包含如下的记录,

{ _id: 1, a: [1, 2], b: 1, category: "A array" }
{ _id: 2, a: 1, b: [1, 2], category: "B array" }

那么,{ a: 1, b: 1 }的组合索引可以使用于上面collection中的每一条记录。
在建立了{ a: 1, b: 1 }的组合索引之后,如果我们试图插入一条document其a,b字段均为数组类型,则MongoDB会插入失败。


参考资料
mongodb官方手册http://docs.mongodb.org/manual/core/index-single/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值