-
对于固定集合可以进行一种特殊的排序, 称为自然排序。自然排序返回结果集中文档的顺序就是文档在磁盘上的顺序。 使用
{"$natural":1}
进行排序。 -
对于大多数集合来说, 自然排序的意义不大, 因为文档的位置经常变动。但是,固定集合中的文档 是按照文档被插入的顺序保存的。自然顺序就是文档的 插入顺序。
//按照自然顺序的正序排序 db.log.find().sort({"$natural":1}); //按照自然顺序的倒序排序 db.log.find().sort({"$natural":-1});
db.collection.getIndexKeys() /*查看集合创建的索引信息*/
{
"_id": ObjectId("570c04a4ad233577f97dc459"),
"score": 1034,
"location": { state: "NY", city: "New York" }
}
#创建正序的索引
db.records.createIndex({score:1},{name:"scoreAscIndex"})
#创建倒序的索引
db.records.createIndex({score:-1},{name:"scoreDescIndex"})
-
创建索引
//通过 . 的这种操作对嵌入的文档建立索引 db.records.createIndex( { "location.state": 1 },{name:"stateIndex"} )
-
下面的查询可以用到这个索引
db.records.find( { "location.state": "CA" } ) db.records.find( { "location.city": "Albany", "location.state": "NY" } )
-
创建索引
db.index.createIndex({"name":1},{"unique":true}) #创建一个唯一索引
-
密集索引 和 稀疏索引的概念
- 密集索引:mongodb索引默认是密集型的。在一个有索引的集合里,每个文档都会有对应的索引项,哪怕文档中没有被索引键也是如此。例如,给文档的name字段建索引,而有的文档并没有name字段,那么name字段索引里会有null值,可以这样查询name为null值的文档:
db.index.find({name: null})。
- 稀疏索引仅包含具有索引字段的文档的条目,即使索引字段包含空值也是如此。索引会跳过缺少索引字段的任何文档。索引是“稀疏的”,因为它不包含集合的所有文档。
- 密集索引:mongodb索引默认是密集型的。在一个有索引的集合里,每个文档都会有对应的索引项,哪怕文档中没有被索引键也是如此。例如,给文档的name字段建索引,而有的文档并没有name字段,那么name字段索引里会有null值,可以这样查询name为null值的文档:
-
使用场景
-
唯一索引会把null看做值, 所以无法 将多个缺少唯一索引中的键的文档插入到集合中. 然而, 在有些情况下, 可能希望唯一索引值对包含相应键的文档生效. 这时可以将 unique 和 sparse 选项组合在一起使用。
db.index.createIndex({"name":1},{"unique":true,"sparse":true});
-
集合中大量文档都不包含被索引键。
-
-
创建索引
db.collection.createIndex( { <field1>: <type>, <field2>: <type2>, ... } ) db.collection.createIndex({"title":1,"description":-1},{name:"title_desc"})
-
排序
- 索引以升序(1)或降序(-1)排序顺序存储对字段的引用。对于单字段索引,键的排序顺序无关紧要,因为MongoDB可以在任一方向上遍历索引。但是,对于复合索引,排序顺序对于确定索引是否可以支持排序操作很重要。
- 只有基于多个查询条件进行排序时,索引方向才是比较重要的。如果只是基于单一键进行排序,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 })
为了确保查询只是用索引就可以完成,应该使用投射来制定不要返回 “_id” 字段 ( 除非它是索引的一部分)。可能需要对不需要查询的字段做索引。
创建空间位置索引 https://blog.csdn.net/zhangzhebjut/article/details/23021073
-
TTL索引是一种特殊索引,通过这种索引MongoDB会过一段时间后自动移除集合中的文档。这对于某些类型的信息来说是一个很理想的特性,例如机器生成的事件数据,日志,会话信息等,这些数据都只需要在数据库中保存有限时间。
-
数据到期
- TTL索引在索引字段值超过指定的秒数后过期文档; 即,到期阈值是索引字段值加上指定的秒数。
- 如果字段是数组,并且索引中有多个日期值,则MongoDB使用数组中的最低(即最早)日期值来计算到期阈值。
- 如果文档中的索引字段不是日期 或包含日期值的数组,则文档将不会过期。
- 如果文档不包含索引字段,则文档不会过期
-
创建
//创建一个10秒以后自动删除 db.log.createIndex({"cTiem":1},{expireAfterSeconds:10}); //写入数据 db.log.createIndex({"cTime":1},{expireAfterSeconds:10})
-
删除操作
- 当您在后台构建TTL索引时,TTL线程可以在索引构建时开始删除文档。如果您在前台构建TTL索引,MongoDB会在索引完成构建后立即开始删除过期的文档。
- TTL索引不保证在到期时立即删除过期数据。文档到期的时间与MongoDB从数据库中删除文档的时间之间可能存在延迟。
- 删除过期文档的后台任务每60秒运行一次。结果,文档可能在文档到期和后台任务运行之间的期间保留在集合中。
- 由于删除操作的持续时间取决于 mongod 实例的工作负载,因此在后台任务运行之间的60秒时间之后,过期数据可能会存在一段时间。
-
部分索引仅索引符合指定过滤器表达式的集合中的文档。通过索引集合中的文档子集,部分索引具有较低的存储要求,并降低了索引创建和维护的性能成本。
-
适用范围
- 等于的表达式。(示例:
field:value
或者$eq
)
$exists:true
表达式$gt
,$gte
,$lt
,$lte
表达式$type
表达式$and
表达式
- 等于的表达式。(示例:
-
创建
复合索引 db.restaurants.createIndex( { cuisine: 1, name: 1 }, { partialFilterExpression: { rating: { $gt: 5 } } } ) 单键索引 db.restaurants.createIndex( { cuisine: 1 }, { partialFilterExpression: { rating: { $gt: 5 } } } ) 可以使用索引的查询语句 db.restaurants.find( { cuisine: "Italian", rating: { $gte: 8 } } ) 不能使用索引的查询语句 db.restaurants.find( { cuisine: "Italian", rating: { $lt: 8 } } )
-
查看某给集合都使用了那些索引
db.users.getIndexes();
-
查看索引是否创建成功
db.getLastError();
-
强制指定使用那个索引
db.books.find({"name":"0book"}).hint(name:-1);
-
重建索引
db.collection.reIndex() # 重建集合上的所有现有索引。
-
如果总体选择性较低,并且如果MongoDB必须读取大量文档以返回结果,那么一些查询可能在没有索引的情况下执行得更快。
db.red.totalIndexSize() #单位:字节
db.red.stats(); #查看集合信息
-
删除集合单个索引
db.accounts.dropIndex({ "tax-id": 1 })
-
删除集合中除
_id
所有索引db.accounts.dropIndexes()
-
默认情况下,在已填充的集合上创建索引会阻止数据库上的所有其他操作。在填充的集合上构建索引时,在索引构建完成之前,保存集合的数据库不可用于读取或写入操作。任何需要对所有数据库(例如listDatabases)进行读或写锁定的操作都将等待前台索引构建完成。
-
可以在创建索引时指定
background
选项. 这样在创建索引时, 如果有新的数据库请求需要处理, 创建索引的过程就会暂停一下, 但仍然会对应用程序影响较大。db.people.createIndex( { zipcode: 1 }, { background: true } )
-
在MongoDB中,排序操作可以通过基于索引中的排序检索文档来获取排序顺序。如果查询计划程序无法从索引获取排序顺序,它将在内存中对结果进行排序。使用索引的排序操作通常比不使用索引的排序操作具有更好的性能。此外,不使用索引的排序操作将在使用32兆字节的内存时中止。
-
如果排序键对应于索引键或索引前缀,MongoDB可以使用索引对查询结果进行排序。甲前缀的化合物指数的是,在索引关键字模式的开始包括一个或多个键的子集。
创建的索引 db.data.createIndex( { a:1, b: 1, c: 1, d: 1 } ) 查询可以使用 db.data.find().sort( { a: 1 } ) { a: 1 } db.data.find().sort( { a: -1 } ) { a: 1 } db.data.find().sort( { a: 1, b: 1 } ) { a: 1, b: 1 } db.data.find().sort( { a: -1, b: -1 } ) { a: 1, b: 1 } db.data.find().sort( { a: 1, b: 1, c: 1 } ) { a: 1, b: 1, c: 1 } db.data.find( { a: { $gt: 4 } } ).sort( { a: 1, b: 1 } ) { a: 1, b: 1 }
-
索引可以支持对索引键模式的非前缀子集的排序操作。为此,查询必须 在排序键之前的所有前缀键上包含相等条件。
创建的索引 { a: 1, b: 1, c: 1, d: 1 } 查询可以使用 db.data.find( { a: 5 } ).sort( { b: 1, c: 1 } ) { a: 1 , b: 1, c: 1 } db.data.find( { b: 3, a: 4 } ).sort( { c: 1 } ) { a: 1, b: 1, c: 1 } db.data.find( { a: 5, b: { $lt: 3} } ).sort( { b: 1 } ) { a: 1, b: 1 }
-
要使用索引进行字符串比较,操作还必须指定相同的排序规则。也就是说,如果操作指定了不同的排序规则,则具有排序规则的索引不能支持对索引字段执行字符串比较的操作。