专栏首页MongoDB中文社区mongodb 索引详解(二)

mongodb 索引详解(二)

1. 单字段索引

MongoDB为文档集合中的任何字段提供完整的索引支持 。默认情况下,所有集合在_id字段上都有索引,应用程序和用户可以添加其他索引以支持重要的查询和操作。

本文档描述了单个字段的升序/降序索引。

1.1 在单个字段上创建升序索引

如:records集合,它包含文档如下:

{
  "_id": ObjectId("570c04a4ad233577f97dc459"),
  "score": 1034,
  "location": { state: "NY", city: "New York" }
}

在records集合的score字段上创建升序索引:

db.records.createIndex( { score: 1 } )

索引规范中字段的值描述了该字段的索引类型。例如,值为1为按对items升序排序的索引。值为-1指定对item降序排序的索引。有关其他索引类型,请参阅 index types

如上索引支持在score字段上选择查询,例如:

db.records.find( { score: 2 } )
db.records.find( { score: { $gt: 10 } } )

1.2 嵌入式字段上创建索引

在嵌入文档中的字段上创建索引,就像文档中的索引顶级字段一样。嵌入字段上的索引与 i索引在嵌入式文档上不同,嵌入文档中的索引包括索引中嵌入文档的最大内容,直到最大的index size。相反,索引在嵌入式字段上允许使用“点符号”来表示嵌入式文档。

如:records集合,它包含文档如下:

{
  "_id": ObjectId("570c04a4ad233577f97dc459"),
  "score": 1034,
  "location": { state: "NY", city: "New York" }
}

以下操作在location.state 字段上创建索引:

db.records.createIndex( { "location.state": 1 } )

创建的索引将支持在字段上选择的查询 location.state,例如:

db.records.find( { "location.state": "CA" } )
db.records.find( { "location.city": "Albany", "location.state": "NY" } )

1.3 在嵌入式文档上创建索引

在整个嵌入式文档上创建索引。

如:records集合,它包含文档如下:

{
  "_id": ObjectId("570c04a4ad233577f97dc459"),
  "score": 1034,
  "location": { state: "NY", city: "New York" }
}

该location字段是一个嵌入式文档,包含嵌入字段 city和state。以下命令在整个location 字段上创建索引:

db.records.createIndex( { location: 1 } )

以下查询可以使用该location字段上的索引:

db.records.find( { location: { city: "New York", state: "NY" } } )

注意

虽然查询可以使用索引,但结果集不包括上面的示例文档。在嵌入文档上执行等值匹配时,字段顺序事项和嵌入文档必须完全匹配。有关查询嵌入式文档的更多信息,请参阅 查询嵌入式文档

1.4 其他注意事项

如果集合包含大量数据,并且您的应用程序需要能够在构建索引时访问数据,请考虑在后台构建索引,如 Background Construction

要为副本集构建或重建索引,请参阅 在副本集上构建索引

某些驱动程序可以使用NumberLong(1)而不是 1作为规范来指定索引。这对索引结果没有任何影响。

2. 复合索引

MongoDB支持复合索引,其中单个索引对集合文档中多个字段[1]的引用。下图说明了两个字段的复合索引示例:

[1] 对于复合索引最多支持32个字段

复合索引可以支持在多个字段上匹配的查询。

2.1创建复合索引

创建复合索引,使用如下语句:

db.collection.createIndex( { <field1>: <type>, <field2>: <type2>, ... } )

索引规范中字段的值描述了该字段的索引类型。例如,值为1对item进行升序排序的索引。值为-1对item进行降序的索引。有关其他索引类型,请参阅 索引类型

注意:

无法创建具有hashed索引类型的复合索引 。如果尝试创建包含散列索引字段的复合索引,则会收到错误。

如:集合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 } )

复合索引中列出的字段的顺序很重要。索引首先按item字段值对文档进行排序,然后对item字段的每个值按照stock字段值进行排序。有关详细信息,请参阅 排序顺序

除了支持在所有索引字段上匹配的查询之外,复合索引还可以支持与索引字段的前缀匹配的查询。也就是说,索引支持对item字段以及字段item和stock字段的查询:

db.products.find( { item: "Banana" } )
db.products.find( { item: "Banana", stock: { $gt: 5 } } )

2.2 排序顺序

索引以升序(1)或降序(-1)排序顺序存储对字段的引用。对于单字段索引,键的排序顺序无关紧要,因为MongoDB可以在任一方向上遍历索引。但是,对于复合索引,排序顺序决定索引是否可以支持排序操作。

Events集合包含字段username和date。应用程序可以发出返回结果的查询,这些查询首先按升序username值排序,然后按降序(即最近更新)date值排序,例如:

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

或返回结果的查询首先按降序username 值排序,然后按升序date值排序,例如:

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

以下索引可以支持这两种排序操作:

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

但是,上述索引不支持按升序username值排序,然后按升序date值排序, 如下所示:

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

有关排序顺序和复合索引的详细信息,请参阅 使用索引对查询结果排序

2.3 前缀

索引前缀是索引字段的 beginning 子集。例如,复合索引:

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

索引具有以下索引前缀:

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

对于复合索引,MongoDB可以使用索引来支持对索引前缀的查询。因此,MongoDB可以在以下字段中使用索引进行查询:

Item字段,

Item字段和location字段

Item字段和location字段和stock字段

MongoDB索引支持查询item和 stock字段,因为item字段对应于前缀。但是,索引在支持查询方面效率不高,因为仅索引item和stock。

但是,MongoDB无法使用索引来支持如下查询,因为没有item字段,所列出的字段无法使用前缀索引:

Location字段,

Stock字段

Location字段和stock字段。

如果集合在在某个字段同时具有复合索引({ a: 1, b: 1 })和前缀索引({ a: 1 }),且两个索引都没有稀疏或唯一约束,则可以删除前缀上的索引({ a: 1 })。当需要使用前缀索引时,MongoDB可以使用复合索引代替。

2.4 索引交集

从2.6版开始,MongoDB可以使用索引交集来完成查询。选择创建支持查询或依赖索引交集,取决于系统的细节。有关详细信息,请参见 索引交集和复合索引

2.5 其他注意事项

如果集合包含大量数据,并且您的应用程序需要能够在构建索引时访问数据,请考虑在后台构建索引,如 Background Construction

要为副本集构建或重建索引,请参阅 Build Indexes on Replica Sets

某些驱动程序可以使用NumberLong(1)而不是 1作为规范来指定索引。这对索引结果没有任何影响。

本文分享自微信公众号 - Mongoing中文社区(mongoing-mongoing)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-07-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 常见问题:索引

    本文档解决了有关MongoDB 索引的一些常见问题 。有关索引的更多信息,请参阅 索引。

    MongoDB中文社区
  • 玩转MongoDB: 索引,速度的引领

    数据库索引与书籍的索引类似,有了索引就不需要翻整本书,数据库可以直接在索引中查找,在索引中找到条目后,就可以直接跳到目标文档的位置,这可以让查找的速度提高几个数...

    MongoDB中文社区
  • 玩转MongoDB: 索引,速度的引领

    数据库索引与书籍的索引类似,有了索引就不需要翻整本书,数据库可以直接在索引中查找,在索引中找到条目后,就可以直接跳到目标文档的位置,这可以让查找的速度提高几个数...

    MongoDB中文社区
  • ES[7.6.x]学习笔记(三)新建索引

    比如我们创建一个名字叫组织机构的索引,这个索引只有两个字段,一个id,一个name。并且这个索引设置为2个分片,2个副本。

    小忽悠
  • ES[7.6.x]学习笔记(三)新建索引

    比如我们创建一个名字叫组织机构的索引,这个索引只有两个字段,一个id,一个name。并且这个索引设置为2个分片,2个副本。

    小忽悠
  • 聚集索引VS非聚集索引

    悟空聊架构
  • 聚集索引VS非聚集索引

    悟空聊架构
  • 深入浅出数据库索引

    前段时间,公司一个新上线的网站出现页面响应速度缓慢的问题, 一位负责这个项目的但并不是搞技术的妹子找到我,让我想办法提升网站的访问速度 ,因为已经有很多用户来投...

    用户1608022
  • 图解MySQL索引--B-Tree(B+Tree)

    看了很多关于索引的博客,讲的大同小异。但是始终没有让我明白关于索引的一些概念,如B-Tree索引,Hash索引,唯一索引…或许有很多人和我一样,没搞清楚概念就开...

    DannyHoo
  • 索引入门:顺序索引

    之前我对索引的了解基本就是主索引和二级索引,此外还经常见到一些其他概念,如聚集索引和非聚集索引,稀疏索引和密集索引等,今天系统整理一下。

    Apache IoTDB

扫码关注云+社区

领取腾讯云代金券