MongoDB---索引(三)

2014-11-24 10:23:43 · 作者: · 浏览: 3
tor.ensureIndex({"username":1},{"unique":true})
默认情况下,insert并不检查文档是否插入过了.所以为了避免插入的文档包含与唯一键重复的值,可能要用安全插入
才能满足要求,这样,在插入这样的文档会看到存在重复键错误的提示.
注意,如果文档中没有对应的键,索引会认为它是以null存储的,所以,如果对某个键建立了唯一索引,但插入了多个
缺少该索引键的文档,这由于文档包含null值而导致插入失败.
www.2cto.com
6.消除重复
当为已有的集合创建唯一索引,可能有些值已经重复了.这样唯一索引将创建失败.但是,可能希望将所有包含重复值
的文档都删掉.dropDups选项就可以保留发现的第一个文档,而删除接下来的有重复值的文档
db.refactor.ensureIndex({"username":1},{"unique":true,"dropDups":true})
如果有重要数据的话,最好还是写个脚本预处理,而不是设置dropDups
7.复合唯一索引
创建复合唯一索引,单个键的值可以重复,只要所有键的值组合起来不同就行.
GridFS是MongoDB中存储大文件的标准方式,其中就用到了复合唯一索引.
8.使用explain和hint
explain是一个非常有用的工具,会帮助你获得查询方面诸多信息.只要对游标调用该方法,可以得到查询细节.
explain会返回一个文档,而不是游标本身,这是与多数游标方法不同之处.


"cursor":"BtreeCursor age_1_username_1"
说明查询使用了age_1_username_1索引.
"nscanned" : 6
6 代表数据库查找了多少个文档.
"n" : 6
这个代表返回文档的数量
"millis" : 0
这个毫秒数表示数据库执行查询的时间.
可以通过索引名字age_1_username_1,来获取索引的详细信息.
db.system.indexes.find({"ns":"test.refactor","name":"age_1_username_1"})
如果 refactor集合有如下两个集合:
db.refactor.ensureIndex({"username":1,"age":1})
db.refactor.ensureIndex({"age":1,"username":1})
要查询用户的用户名和年龄:
db.refactor.find({"age":{"$gt":30},"username":"refactor"}).explain()
这个会用"username":1,"age":1的索引,因为是要求精确查询用户名和年龄范围,数据库自己调换了查询项的顺序. www.2cto.com
db.refactor.find({"age":24,"username":/.*/}).explain()
这个会用"age":1,"username":1的索引
如果发现MongoDB用了非预期的索引,可以用hint强制使用某个索引.如:
db.refactor.find({"age":{"$gt":30},"username":"refactor"}).hint({"age":1,"username":1}).explain()
多说情况下,这种指定没有必要,MongoDB的查询优化器很智能,会替你选择用哪个索引.初次做某个查询时,
查询优化器会同时尝试各种查询方案.最先完成的被确定使用,其他的则终止掉.查询方案被记录下来,以备日后
应对相同键的查询.查询优化器定期重试其他方案,以防止因为添加新数据后,之前的方案不是最优了.只要关心
给查询优化器建立可以选择的索引就可以了.
9.索引管理
索引的元信息存储在每个数据库的system.indexes集合中.这是一个 保留集合(遍历数据库中所有集合时要小心,因为
通常我们不想对这个集合进行操作),不能对其插入或删除文档.操作只能通过ensureIndex或dropIndexes进行.
system.indexes集合中包含每个索引的详细信息.system.namespaces集合包含索引的名字.
10.修改索引
随着应用程序的使用,数据库的数据或查询发生了改变,原来的索引不在使用.可以使用ensureIndex随时向数据库
添加新的索引.
db.refactor.ensureIndex({"username":1,"age":1},"background":true)
建立索引即耗时又费力,还要消耗更多资源.使用{"background":true}选项可以使这个过程在后台完成
,同时正常处理请求.要是不使用background这个选项,数据库会阻塞建立索引期间的所有请求.
阻塞的做法会使索引建立的更快.即使在后台创建索引也会对正常操作有影响,所以最好选择无关紧要的时间.
为已由文档创建索引比先创建索引再插入所有文档要稍快一些.当然,要是集合的数据从无到有,事先创建一个索引.
要是索引没用了,可以使用dropIndexes加上索引名称将其删除.通常,要查一下system.indexes集合来找出索引名,
以为自动生成的名字会因驱动程序的不同而不同.
db.runCommand({"dropIndexes":"blog","index":"author.name_1"})
要删除所有索引
db.runCommand({"dropIndexes":"blog","index":"*"})
www.2cto.com
11.地理空间索引
随着移动设备的出现,找到离当前位置最近的N个场所的查询越来越多.MongoDB为坐标平面查询提供了专门
的索引,称作 地理空间索引
地理空间索引也是使用ensureIndex来创建,只不过不是"1"或"-1",而是"2d"
db.map.insert({"gps":[1,100]})
db.map.insert({"gps":{"x":-30,"y":30}})
db.map.insert({"gps":{"latitude":-60,"longitude":30}})
db.map.ensureIndex({"gps":"2d"})
"gps"键的值必须是某种形式的一对值:一个包含两个元素的数组或者是包含两个键的内嵌文档.内嵌文档
的键名可以是随意的,如{"gps":{"refactor":-60,"refactor1":30}
默认情况下,地理空间索引的值是-180~180(对经纬度很方便).要是想用其他值
db.map.ensureIndex({"gps":"2d"},{"min":-1000,"max":1000})
这样就创建了一个2000光年见方的空间索