• MongoDB索引


     ---------------------MongoDB索引---------------------
    1、索引简介:
        1、扩展索引
            创建索引时要考虑如下问题:
                会做什么样的查询?其中那些键需要索引?
                每个键的索引方向是怎样的?
                如何应对扩展?有没有种不同的键的排列可以使用常用数据更多的保留在内存中?
                    例:一个存储用户状态的表
                        db.status.ensureIndex({"user":1,"date":1}):用户在前
                        db.status.ensureIndex({"date":1,"user":1}):时间在前
        2、索引内嵌文档中的键
            为内嵌文档的键建立索引和为普通的键创建索引没有什么区别。
            db.blog.ensureIndex({"comments.date":1})
        3、为排序创建索引
            随着集合的增长,需要针对查询中大量的排序做索引。如果对没有索引的键调用sort,MongoDB需要将所有数据提取到内存来排序。因此,可以做无索引排序是有个上限的,那就是不可能在内存里面做T级别数据的排序。一旦集合大到不能在内存中排序,MongoDB就会报错。
            按照排序来索引以便让MongoDB按照顺序提取数据,这样就能排序大规模数据,而不必担心用过内存。
        4、索引名称
            集合中的每个索引都有一个字符串类型的名字,来唯一标识索引,服务器通过这个名字来删除或者操作索引。索引名类似keyname1_dir1_keyname2_dir2...keynameN_dirN这种形式,其中keynameX代表索引的键,dirX代表索引的方向(1或-1).要是索引的键特别多,这样命名就略显笨拙。
            ensureIndex创建索引是可以进行名字的创建工作
            db.foo.ensureIndex({"a":1,"b":2,"c":3...,"z":1},{"name":"alphabet"})       
     
    2、唯一索引:
        1、唯一索引可以保存集合的每一个文档的指定键都有唯一值。
            db.集合名.ensureIndex({"username":1},{"unique":true})
        2、消除重复:当为已有的集合创建索引,可能有些值已经有重复了。若是真的发生这种情况,那么索引的创建就会失败。有些时候,可能希望将所有包含重复值的文档都删掉。dropDups选项就可以保留发现的第一个文档,而删除接下来的有重复值的文档。
            db.集合名.ensureIndex({"username":1},{"unique":true,"dropDups":true})
     
        3、复合唯一索引
            创建复合唯一索引的时候单个键的值可以相同,只要所有键的值组合起来不同就好。
     
    3、使用explan和hint
        1、explain:
            1、explain是一个非常有用的工具,会帮助你获得查询方面诸多有用的信息。只要对游标调用该方法,就可以得到查询细节。explain会返回一个文档,而不是游标本身,这是与多数游标方法不同之处。
            db.集合名.find().explain()
            explain会返回查询使用的索引情况(如果有的话),耗时及扫描文档数的统计信息。
            例:
                db.people.find({"age":18}).sort({"username":1}):
                这是就搞不太准确数据库到底用没用已经创建的索引,或者到底效率如何。使用explain就会得到当前查询所使用的索引,消耗了多少时间,以及数据库需要扫描多少文档才能得到结果。
            2、对应参数的分析:
                1、"cursor":"BasicCursor":这说明查询没有使用索引/"cursor":"BasicCursor age_1":这说明查询使用了索引
                2、"nscanned":64:这个数字代表数据库查询找了多少个文档。大家都想让这个数字尽可能地接近返回结果的数量。
                3、"n":64:这个代表返回文档的数量。
                4、"millis":0:这个毫秒数表示数据库执行查询的时间。0是非常理想的成绩。
     
        2、hint:
            如果发现MongoDB用了非预期的索引,可以用hint强制使用某个索引。
            例:
                db.c.find({"age":14,"username":/.*/}).hint({"username":1,"age":1})
     
    4、索引的管理:
        1、索引的元信息存储在每个数据库的system.indexes集合中。这是一个保留集合,不能对其插入或删除文档。操作只能通过ensureIndex或者dropIndexes进行。system.indexes集合包含每个索引的详细信息,同时system.namespaces集合也含有索引的名字。
        2、索引的创建:
            语法:
            ensureIndex()方法基本语法格式如下所示:
            >db.COLLECTION_NAME.ensureIndex({KEY:1})
            注:从mongoDB 3.0开始ensureIndex被废弃,今后都仅仅是db.collection.createIndex的一个别名。
            语法中 Key 值为你要创建的索引字段,1为指定按升序创建索引,-1即为降序。
            例:
                db.mongoDBtest.ensureIndex({"name":1,"age":1})
                db.mongoDBtest.ensureIndex({"age":1,"name":1})
        3、索引的修改:
            使用ensureIndex随时可以向现有集合添加新的索引:
                db.mongoDBtest.ensureIndex({"username":1},{"background":true})
            建立索引既耗时也费力,还需要消耗很多资源。使用{"background":true}选项可以使这个过程在后台完成,同时正常处理请求。要是不包括background这个选项,数据库会堵塞建立索引期间的所有请求;堵塞的做法会让索引建立更快,同时也意味着应用在此期间不能应答。即便在后台进行也会对正常操作有些影响,所以最好选在无关紧要的时刻。后台创建索引也会增加些负载,好在不会让服务器停机。
        4、索引的删除:
            索引没用的时,便可以用dropIndexes加上索引名将其删除。通常,要查一下system.indexes集合来找出索引名,
                db.runCommand({"dropIndexes":"mongoDBtest","index":"alphabet"})
            要删除所有索引,可以将index的值赋为*:
                db.runCommand({"dropIndexes":"mongoDBtest","index":"*"})
            注:另外一种删除索引的方式就是删除集合。也会删除_id索引(还有集合中的所有文档)。删除集合的所有文档(用remove的方式)并不影响索引,当有新文档时还是会再生的。
     
    5、地理空间索引
        1、复合地理空间索引
            还有一种查询变得越来越流行(尤其是随着移动设备的出现):找到离当前位置最近的N个场所。MongoDB为坐标平面查询提供了专门的索引,称作地理空间索引。
            创建方式:复合地理空间索引还是用ensureIndex来创建,只不过参数不是1或-1,而是“2d”:
                db.map.ensureIndex({"gps":"2d"})
                例:
                    db.star.trek.ensureIndex({"light-years":"2d"},{"min":-180,"max":180})
     
    参考:《MongoDB权威指南》
  • 相关阅读:
    我参与过的开源项目
    chineking / WeiboCrawler / wiki / Home — Bitbucket
    PIL应用之生成验证码图片
    hurl
    Hadoop笔记之安装及伪分布式模式配置
    httpbin(1): HTTP Client Testing Service
    动态规划求编辑距离 残阳似血的博客
    cppreference.com
    sscanf
    在python中定义二维数组
  • 原文地址:https://www.cnblogs.com/qingtianyu2015/p/5944220.html
Copyright © 2020-2023  润新知