mongoDB 学习笔记(四)索引 索引管理 空间索引

索引

mongodb中的索引在概念上和大多数关系型数据库如MySQL是一样的。当你在某种情况下需要在MySQL中建立索引,这样的情景同样适合于MongoDB。

索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟。

首先我们创建一个简单的索引看一下用索引的查询效率,准备数据:

for(var i = 0 ; i<200000 ;i++){
	db.books.insert({number:i,name:i+"book"})
}

创建简单索引

var start = new Date()
            db.books.find({number:65871})
            var end = new Date()
            end - start

结果:

添加索引:

db.books.ensureIndex({number:1})

添加成功:

查询结果:

 注意事项

 1.创建索引的时候注意1是正序创建索引-1是倒序创建索引
 2.索引的创建在提高查询性能的同事会影响插入的性能,对于经常查询少插入的文档可以考虑用索引
 3.符合索引要注意索引的先后顺序
 4.每个键全建立索引不一定就能提高性能呢,索引不是万能的
 5.在做排序工作的时候如果是超大数据量也可以考虑加上索引, 用来提高排序的性能

索引的名称

1、使用VUE查看索引名称

默认索引名称字段名称number_1,倒序索引-1

2、使用自定义的索引名称

 db.books.ensureIndex({name:-1},{name:"bookname"})

唯一索引

如何解决文档books不能插入重复的数值, 建立唯一索引

db.books.ensureIndex({name:-1},{unique:true})

先删除之前建立的name:-1的索引,添加索引

添加字段,添加失败

如果建议唯一索引之前已经有重复数值如何处理
 

db.books.ensureIndex({name:-1},{unique:true,dropDups:true})

强制查询使用指定的索引,指定索引必须是已经创建了的索引
  

db.books.find({name:"1book",number:1}).hint({name:-1})


索引管理

1.在shell查看数据库已经建立的索引

db.system.indexes.find()
db.system.namespaces.find()


2.后台执行,为了不影响查询我们可以叫索引的创建过程在后台

db.books.ensureIndex({name:-1},{background:true})


3.删除索引批量和精确删除索引

db.runCommand({dropIndexes : "books" , index:"name_-1"})
db.runCommand({dropIndexes : "books" , index:"*"})

 空间索引

1、mongoDB提供强大的空间索引可以查询出一定范围的地理坐标,准备数据

var map = [{
  "gis" : {"x" : 185,"y" : 150}
},{
  "gis" : {"x" : 70,"y" : 180}
},{
  "gis" : {"x" : 75,"y" : 180}
},{
  "gis" : {"x" : 185,"y" : 185}
},{
  "gis" : {"x" : 65,"y" : 185}
},{
  "gis" : {"x" : 50,"y" : 50}
},{
  "gis" : {"x" : 50,"y" : 50}
},{
  "gis" : {"x" : 60,"y" : 55}
},{
  "gis" : {"x" : 65,"y" : 80}
},{
  "gis" : {"x" : 55,"y" : 80}
},{
  "gis" : {"x" : 0,"y" : 0}
},{
  "gis" : {"x" : 0,"y" : 200}
},{
  "gis" : {"x" : 200,"y" : 0}
},{
  "gis" : {"x" : 200,"y" : 200}
}]
for(var i = 0;i<map.length;i++){
	db.map.insert(map[i])
}

2、建立索引

添加2D索引,默认会建立一个[-180,180]之间的2D索引,由于数据又 超过180的所以默认建立索引会失败。使用min和max设置索引范围。

db.map.ensureIndex({"gis":"2d"})
db.map.ensureIndex({"gis":"2d"},{min:-1,max:201})


 

3、查询

//查询点(70,180)最近的3个点
db.map.find({"gis":{$near:[70,180]}},{gis:1,_id:0}).limit(3)
//查询以点(50,50)和点(190,190)为对角线的正方形中的所有的点
db.map.find({gis:{"$within":{$box:[[50,50],[190,190]]}}},{_id:0,gis:1})
//查询出以圆心为(56,80)半径为50规则下的圆心面积中的点
db.map.find({gis:{$within:{$center:[[56,80],50]}}},{_id:0,gis:1})