zoukankan      html  css  js  c++  java
  • 学习MongoDB 八: MongoDB索引(索引限制条件)(二)

    一、简介

          我们上一篇介绍了索引基本操作,通过db.collection.createIndex(keys, options)语法创建索引,我们继续介绍地理空间索引、索引的限制,使我们在MongoDB时能提高查询效率。

        索引的语法:

                    db.collection.createIndex(keys,options)

          

        options 参数说明

           

           

     

           

    二.地理空间索引

          我们生活上用到地理位置越多越多,所以存储经纬度就多了,查地理位置就多了,为了提高在MongoDB查询效率,我们建立地理空间索引。

     

       1.创建地理空间索引

           语法:

                

    1. db.collection.createIndex({ <location field> : "2d" ,
    2. <additionalfield> : <value> } ,
    3. {<index-specification options> } )

         index-specification参数说明:

              { min : <lower bound> , max :<upper bound> }

       

         我们经常创建经纬度的格式有几种,例如:location:[ 50, 40 ]、location :{ lng :50 ,lat : 40}

    1. > db.places.find()
    2. { "_id" :ObjectId("55ad0df063ea39b3057bdeef"), "onumber" : 1,"date" : "2015-07
    3. -01", "cname" :"zcy", "location" : [ -10, 100 ] }
    4. { "_id" :ObjectId("55ad0e0463ea39b3057bdef0"), "onumber" : 2,"date" : "2015-07
    5. -02", "cname" :"zcy", "location" : [ 10, 60 ] }
    6. { "_id" :ObjectId("55ad0e1663ea39b3057bdef1"), "onumber" : 3,"date" : "2015-07
    7. -03", "cname" :"zcy", "location" : [ 100, 150 ] }
    8. { "_id" :ObjectId("55ad0e2463ea39b3057bdef2"), "onumber" : 4,"date" : "2015-07
    9. -04", "cname" : "zcy","location" : [ 150, 200 ] }
    10. { "_id" :ObjectId("55ad0e3263ea39b3057bdef3"), "onumber" : 5,"date" : "2015-07
    11. -05", "cname" :"zcy", "location" : [ -100, 100 ] }

      例子:

        >db.places.createIndex({location:"2d"})

         

       地理空间索引默认值的范围为-180到180,如果值已经存在超过了200时,就会建索引失败:

             "errmsg" : "point not in interval of [ -180, 180 ] ::caused by :: { _id: ObjectId('55ad07bc63ea39b3057bdeed'),onumber: 5.0, date: "2015-07-05", cnam

    e: "zcy", location: [ 100.0,200.0 ] }", "code" : 13027

          

         我们可以建立一个二维地理空间索引的位置范围以外的默认,创建索引时使用最小和最大选项。

         

         语法:

               

    1. db.collection.createIndex( {<location field> : "2d" } ,
    2. {min : <lower bound> , max : <upper bound> } )

         例子:

          >db.places.createIndex({location:"2d"},{min:-200,max:200})

        地理空间索引默认值的范围为-200到200

     

      2.查询平面上的点

          我们可以使用$near或者geoNear Command查询,可以使用limit()函数,若不指定,默认是返回100条文档。

     

        (1)      精确的查询

                    例子:

           > db.places.find({location:[60,100]})

            

           我们查询经纬度为[60,100]

     

       (2)  $near查询

      

            我们需要查询范围内的经纬度有哪些

           语法:

    1. db.collection.find( {<location field> :
    2. {$near : [ <x> , <y> ]
    3. } } )

        例子:

          > db.places.find({location:{$near:[100,200]}})


             

     

           我们查询目标点[100,200]距离最近的100个点,然后是按最接近的排序

     

    (3)geoNearCommand查询

     

          geoNear Command查询根db.collection.find()查询相似

        

         语法:

        db.runCommand( { geoNear:<collection>, near: [ <x> , <y> ] } )

        例子:

          

    1.  
    2. > db.runCommand( {geoNear:"places", near: [ -100,100] } )
    3. {
    4. "results" :[
    5. {
    6. "dis" : 0,
    7. "obj" : {
    8. "_id" : ObjectId("55ad0e3263ea39b3057bdef3"),
    9. "onumber" : 5,
    10. "date" : "2015-07-05",
    11. "cname" : "zcy",
    12. "location" : [
    13. -100,
    14. 100
    15. ]
    16. }
    17. },
    18. {
    19. "dis" : 90,
    20. "obj" : {
    21. "_id" : ObjectId("55ad0df063ea39b3057bdeef"),
    22. "onumber" : 1,
    23. "date" : "2015-07-01",
    24. "cname" : "zcy",
    25. "location" : [
    26. -10,
    27. 100
    28. ]
    29. }
    30. },
    31. {
    32. "dis" : 117.04699910719626,
    33. "obj" : {
    34. "_id" : ObjectId("55ad0e0463ea39b3057bdef0"),
    35. "onumber" : 2,
    36. "date" : "2015-07-02",
    37. "cname" : "zcy",
    38. "location" : [
    39. 10,
    40. 60
    41. ]
    42. }
    43. },
    44. {
    45. "dis" : 206.15528128088303,
    46. "obj" : {
    47. "_id" : ObjectId("55ad0e1663ea39b3057bdef1"),
    48. "onumber" : 3,
    49. "date" : "2015-07-03",
    50. "cname" : "zcy",
    51. "location" : [
    52. 100,
    53. 150
    54. ]
    55. }
    56. },
    57. {
    58. "dis" : 269.2582403567252,
    59. "obj" : {
    60. "_id" : ObjectId("55ad0e2463ea39b3057bdef2"),
    61. "onumber" : 4,
    62. "date" : "2015-07-04",
    63. "cname" : "zcy",
    64. "location" : [
    65. 150,
    66. 200
    67. ]
    68. }
    69. }
    70. ],
    71. "stats" : {
    72. "nscanned" : NumberLong(5),
    73. "objectsLoaded" : NumberLong(5),
    74. "avgDistance" : 136.4921041489609,
    75. "maxDistance" : 269.2582403567252,
    76. "time" : 52
    77. },
    78. "ok" : 1
    79. }

     

    4.查询曲面上定义的点

     (1)$box

     (2)$polygon

    ( 3)$center(defines a circle)

      这边就不做具体介绍了,可以到官方文档查看:http://docs.mongodb.org/manual/tutorial/query-a-2d-index/

     

     三.索引的限制

      我们第二章介绍索引的基本创建,我们现在创建索引时加上限制条件,比如唯一索引等

     

       1.      唯一索引

               

           对字段设置唯一索引时,可以保证字段都是唯一性

                   

            语法:

         db.collection.createIndex({field1:boolean, field2:boolean },{unique: true})

          (1)新建唯一索引

                   例子:  

              > db.orders.createIndex({onumber:1},{unique:true})

                     我们创建了onumber为唯一索引

                     当我们插入相同的onumber时,会新增失败

                        

                   说明:我们在新建字段为唯一索引时,对应的字段不存在,索引会将其作为null存储,如果对文档新增第一条时,没保存字段对应的值时,会以null保存,第二条还是对指定字段对应的值,新增数据时,之前已经存在null,所以会导致新增失败。

     

      (2)对文档中已经存在的相同的字段新建唯一索引

     

               我们文档中已经有数据时,我们新建唯一索引

              例子:

           >db.orders.createIndex({onumber:1},{unique:true})

                      

     

           我们集合中的onumber字段值已经有重复,所以会导致创建唯一性索引失败

           

           唯一索引不能够创建在具有重复值的键上,如果你一定要在这样的键上创建,使用dropDups参数,系统对重复值的键上只保留第一条记录,剩下的记录会被删除

       例子:

          >db.orders.createIndex({onumber:1},{unique:true,dropDups:true})

        2.      索引的名称

                我们之前在创建索引时,没指定索引名称,MongoDB会生成一个默认的索引名称,我们可以通过name参数来指定我们新建索引的名称

                语法:

              db.collection.createIndex({field1:boolean,field2:boolean },{name: "index_name"}) 

             例子:

            >db.orders.createIndex({onumber:1},{name:"index_onumber"})

                    

      

             我们onumber字段新建一个索引名称为index_onumber的索引

     

       3.      后台方式创建索引

                 background 在创建索引时,会阻塞MongoDB其它操作,比如查询MongoDB时,background为trues时可指定以后台方式创建索引,默认值时false

     

                语法:

             db.collection.createIndex({{field1:boolean,field2:boolean }} },{background: true})

                例子:

             > db.orders.createIndex({cname:1},{background:true}<span style="font-size:18px;">)</span>

         4.      稀疏索引  

             sparse:稀疏索引只包含有索引字段的文档,即使索引字段包含空值,指数跳过缺少索引字段。索引是“稀疏的”,因为它不包含集合的所有文档。与之相反,非稀疏索引中包含一个集合中的所有文档,这些文档中不包含索引字段的空值。类似于$exists用来判断一个field是否存在

            语法

            db.collection.createIndex({{field1:boolean,field2:boolean }} },{ sparse: true})

            例子:

           >db.orders.createIndex({onumber:1},{sparse:true})

                

     

            我们查询时,onumber为null为4条记录,我们以onumber为nul做为查询条件时,没使用到索引。

     

            而我们以onumber为1作为查询条件时,有使用到索引。

             

     

                稀疏索引只包含有索引字段的文档,即使索引字段包含空值,指数跳过缺少索引字段

     

     

    四、索引的信息

     

      1.        强制索引

          我们在对MongoDB查询时,可以使用hint强制用某个索引

        语法:

        db. collection.find().hint(“index_name”)

           例子:

        >db.orders.find({onumber:1}).hint("onumber_1")

         我们强制使用onumber 字段索引名称为onumber_1的索引

     

         MongoDB的查询优化器非常智能,会替你选择该用哪个索引,多数情况下不需要指定的。

     

       2.        执行计划

     

          MongoDB 提供了一个 explain 命令让我们获知系统如何处理查询请求。利用 explain 命令,我们可以很好地观察系统如何使用索引来加快检索,同时可以针对性优化索引。

    1. >db.orders.find({onumber:1}).hint("onumber_1").explain()
    2. {
    3. "cursor" : "BtreeCursor onumber_1",
    4. "isMultiKey" : false,
    5. "n" : 1,
    6. "nscannedObjects" : 1,
    7. "nscanned" : 1,
    8. "nscannedObjectsAllPlans" : 1,
    9. "nscannedAllPlans" : 1,
    10. "scanAndOrder" : false,
    11. "indexOnly" : false,
    12. "nYields" : 0,
    13. "nChunkSkips" : 0,
    14. "millis" : 77,
    15. "indexBounds" : {
    16. "onumber" : [
    17. [
    18. 1,
    19. 1
    20. ]
    21. ]
    22. },
    23. "server" : "zhengcy-PC:27017",
    24. "filterSet" : false
    25. }



     

      对一些比较重要的参数说明:

        1) n:当前查询返回的文档数量。

        2)millis:当前查询所需时间,毫秒数。

       3)indexBounds:当前查询具体使用的索引。

       4)nscanned:扫描document的行数。

       5)cursor:返回游标类型(BasicCursor和BtreeCursor),我们这边使用BtreeCursor类型。

       6)nscannedObjects:被扫描的文档数量。

       7)scanAndOrder:是否在内存中排序。

  • 相关阅读:
    Eclipse常用快捷键
    java中构造方法及其作用
    jsp的验证码实现
    request.getParameter()与request.setAttribute()的区别 (转载)
    HTML表单操作的记录
    Java Collection(转载)
    Java中StringBuffer类append方法的使用
    java中string.trim()函数的使用
    doGet与doPost的区别
    celery
  • 原文地址:https://www.cnblogs.com/cuihongyu3503319/p/9453033.html
Copyright © 2011-2022 走看看