本文是在浏览 MongoDB 官网文档时记录的一些次要概念,更多细节能够查看文中的参考链接。
查看以后 db 索引
db.COLLECTION_NAME.getIndexes()[ { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "newDB.sites" }, { "v" : 1, "key" : { "name" : 1, "domain" : -1 }, "name" : "name_1_domain_-1", "ns" : "newDB.sites" }]
单字段索引 single field
在单个字段上创立索引,1示意升序,-1示意降序。
对于单字段索引来说,指定升序降序无关紧要,查问时抉择升序降序性能是一样的。
但对于复合索引来说,查问须要合乎索引的程序能力走上索引。
# 创立索引db.records.createIndex( { score: 1 } )# 查问应用索引db.records.find( { score: 2 } )db.records.find( { score: { $gt: 10 } } )
嵌入式文档的外部字段上的索引
什么是嵌入式字段?就是这个字段的值也是一个文档。MongoDB 反对在嵌入式文档的外部字段上建设索引
# location 是一个文档{ "_id": ObjectId("570c04a4ad233577f97dc459"), "score": 1034, "location": { state: "NY", city: "New York" }}# 在location上面的state字段上创立索引db.records.createIndex( { "location.state": 1 } )# 查问db.records.find( { "location.state": "CA" } )db.records.find( { "location.city": "Albany", "location.state": "NY" } )
在嵌入式文档自身建设的索引
还拿下面例子来讲,能够间接在 location 下面建设索引
{ "_id": ObjectId("570c04a4ad233577f97dc459"), "score": 1034, "location": { state: "NY", city: "New York" }}# 间接在location上建设索引db.records.createIndex( { location: 1 } )# 应用索引db.records.find( { location: { city: "New York", state: "NY" } } )
复合索引 compound
在多个字段上建设的索引,需别离指定每个字段的升降序规定。查问时须要合乎升降序规定或合乎反向规定,能力走上索引。
复合索引最多只能反对32个字段。
复合索引反对前缀查问。
# 文档构造{ "_id": ObjectId(...), "item": "Banana", "category": ["food", "produce", "grocery"], "location": "4th Street Store", "stock": 4, "type": "cases"}# 建设索引 以item升序 且 stock升序简历索引。含意是,当文档的item值雷同时,按stock升序排序db.products.createIndex( { "item": 1, "stock": 1 } )# 复合索引也反对前缀查问db.products.find( { item: "Banana" } )db.products.find( { item: "Banana", stock: { $gt: 5 } } )
复合索引的索引程序
索引以升序(1)或降序(-1)排序顺序存储对字段的援用。对于单字段索引,键的排序程序无关紧要,因为 MongoDB 能够在任一方向上遍历索引。然而,对于复合索引,属性的程序决定了索引是否反对后果集的排序。
# 假如合乎索引如下db.events.createIndex( { "username" : 1, "date" : -1 } )# 这个索引反对如下两种查问db.events.find().sort( { username: 1, date: -1 } )db.events.find().sort( { username: -1, date: 1 } )# 但不反对上面的查问db.events.find().sort( { username: 1, date: 1 } )# 即只能从索引一头儿查问能力走上索引
复合索引中的前缀索引
# 假如有如下复合索引{ "item": 1, "location": 1, "stock": 1 }# 则可反对上面两种前缀索引查问{ item: 1 }{ item: 1, location: 1 }# 同时也反对前缀的局部匹配,即如下查问可用上item字段的前缀索引{ item: 1, stock: 1 }
多键索引 multikey
反对对数组元素内的字段做索引。
# 如果field 是一个数组,则主动建设多键索引,无需非凡指定db.coll.createIndex( { <field>: < 1 or -1 > } )
但mongodb限度不能够在过个数组上做复合索引。
# 上面这种状况,不能够在 {a:1, b:1} 上做索引{ _id: 1, a: [ 1, 2 ], b: [ 1, 2 ], category: "AB - both arrays" }
文本索引 text
MongoDB 提供文本索引以反对对字符串内容的文本搜寻查问。text 索引能够蕴含任何值为字符串或字符串元素数组的字段。
# 在comments字段上建设文本索引db.reviews.createIndex( { comments: "text" } )# 在多个字段上建设text索引db.reviews.createIndex( { subject: "text", comments: "text" } )
文本索引还能够设置反对的语言、管制相关性分数权重排序、限度条目等,更多查看 https://www.mongodb.com/docs/manual/core/index-text/
通配符索引
有时查问的维度可能不固定,会依照多个字段去查问
# 数据文档{ "userMetadata" : { "likes" : [ "dogs", "cats" ] } }{ "userMetadata" : { "dislikes" : "pickles" } }{ "userMetadata" : { "age" : 45 } }{ "userMetadata" : "inactive" }# 能够建设通配符索引db.userData.createIndex( { "userMetadata.$**" : 1 } )# 反对以下查问db.userData.find({ "userMetadata.likes" : "dogs" })db.userData.find({ "userMetadata.dislikes" : "pickles" })db.userData.find({ "userMetadata.age" : { $gt : 30 } })db.userData.find({ "userMetadata" : "inactive" })
https://www.mongodb.com/docs/manual/core/index-wildcard/
2dsphere 和 2d 索引
别离是对计算相似地球的球体上的几何形态的查问的索引,和对存储为二维立体上的点的数据应用2d 索引
https://www.mongodb.com/docs/manual/core/2dsphere/
https://www.mongodb.com/docs/manual/core/2d/
索引个性
unique 惟一索引
惟一索引确保索引字段不会存储反复值,默认状况下,MongoDB 在创立汇合期间在 _id 字段上创立一个惟一的索引。
# 单字段上创立惟一索引db.members.createIndex( { "user_id": 1 }, { unique: true } ) # 多字段上复合惟一索引db.members.createIndex( { groupNumber: 1, lastname: 1, firstname: 1 }, { unique: true } )# 数组类型的多键索引# 文档构造如下:{ _id: 1, a: [ { loc: "A", qty: 5 }, { qty: 10 } ] }# 建设索引db.collection.createIndex( { "a.loc": 1, "a.qty": 1 }, { unique: true } )
partial 局部索引
只对满足指定筛选器表达式的文档做索引,这样索引量更少,性能更高。
# 对rating>5的文档做索引db.restaurants.createIndex( { cuisine: 1, name: 1 }, { partialFilterExpression: { rating: { $gt: 5 } } })
sparse 稠密索引
只对含有索引字段的文档建设索引,字段值是空值也建设。
与之对应的非稠密索引,则是会对空缺字段存储空值。
因为稠密索引中有局部文档未被计入索引中,所以在稠密索引上count查问不精确
db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )
其余索引个性:
- ttl 有效期索引
- 不辨别大小写索引
索引穿插 Index Intersection
指同时利用多个索引
# 两个独立索引{ qty: 1 }{ status: 1, ord_date: -1 }# 上面的查问能够同时利用两个索引,也就是索引交加db.orders.find( { qty: { $gt: 10 } , status: "A" } )
索引交加跟复合索引很像:复合索引性能更高,要求更严格。索引交叉性能差一些,但更灵便。
# 复合索引如下{ status: 1, ord_date: -1 }# 复合索引反对如下查问db.orders.find( { status: { $in: ["A", "P" ] } } )db.orders.find( { ord_date: { $gt: new Date("2014-02-01") }, status: {$in:[ "P", "A" ] } })# 但无奈反对上面的查问db.orders.find( { ord_date: { $gt: new Date("2014-02-01") } } )db.orders.find( { } ).sort( { ord_date: 1 } )# 如果建设两个独立的索引,则能够用到这两个索引的索引交加{ status: 1 }{ ord_date: -1 }
但有一种状况不能走索引穿插:当查问须要排序时,而排序字段不在查问谓词(查问字段)中时,无奈利用索引交加。
换句话说,只有在查问谓词中的字段可能组成索引交加的,能力利用索引交加。
# 有如下四种索引{ qty: 1 }{ status: 1, ord_date: -1 }{ status: 1 }{ ord_date: -1 }# 这条无奈利用索引交加,查问中只有qty,而按status排序db.orders.find( { qty: { $gt: 10 } } ).sort( { status: 1 } )# 这条能够利用,查问中qty和 status+ord_date组成了索引交加db.orders.find( { qty: { $gt: 10 } , status: "A" } ).sort( { ord_date: -1 } )
业务中应用复合索引还是索引交加,须要取决于零碎具体情况。
治理索引,索引的增删查改
https://www.mongodb.com/docs/manual/tutorial/manage-indexes/
掂量索引的应用状况
db.collection.explain()
查看执行打算db.people.find({ name: "John Doe", zipcode: { $gt: "63000" } }).hint( { zipcode: 1 } )
强制走某索引
索引策略:索引的应用和排序
字符串比拟时,须要思考字符串的字符集,须要与建设索引时统一能力走索引。
排序时,也合乎前缀匹配
复合索引反对正模式与反模式
本文由mdnice多平台公布