學習MongoDB 八: MongoDB索引(索引限制條件)(二),mongodb索引

來源:互聯網
上載者:User

學習MongoDB 八: MongoDB索引(索引限制條件)(二),mongodb索引
一、簡介

      我們上一篇介紹了索引基本操作,通過db.collection.createIndex(keys, options)文法建立索引,我們繼續介紹地理空間索引、索引的限制,使我們在MongoDB時能提高查詢效率。

 

    索引的文法:

                db.collection.createIndex(keys,options)

      

    options 參數說明

       

       


       

二.地理空間索引

      我們生活上用到地理位置越多越多,所以儲存經緯度就多了,查地理位置就多了,為了提高在MongoDB查詢效率,我們建立地理空間索引。

 

   1.建立地理空間索引

       文法:

            

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

     index-specification參數說明:

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

   

     我們經常建立經緯度的格式有幾種,例如:location:[ 50, 40 ]、location :{ lng :50 ,lat : 40}


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

      

     我們可以建立一個二維地理空間索引的位置範圍以外的預設,建立索引時使用最小和最大選項。

     

     文法:

           

      db.collection.createIndex( {<location field> : "2d" } ,                                 {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查詢

  

        我們需要查詢範圍內的經緯度有哪些

       文法:

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


    例子:

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

         


       我們查詢目標點[100,200]距離最近的100個點,然後是按最接近的排序

 

(3)geoNearCommand查詢


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

    

     文法:

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


    例子:

      

       > db.runCommand( {geoNear:"places", near: [ -100,100] } ){        "results" :[                {                       "dis" : 0,                       "obj" : {                               "_id" : ObjectId("55ad0e3263ea39b3057bdef3"),                               "onumber" : 5,                               "date" : "2015-07-05",                               "cname" : "zcy",                               "location" : [                                        -100,                                        100                               ]                        }                },                {                       "dis" : 90,                       "obj" : {                               "_id" : ObjectId("55ad0df063ea39b3057bdeef"),                               "onumber" : 1,                               "date" : "2015-07-01",                               "cname" : "zcy",                               "location" : [                                       -10,                                        100                               ]                        }                },                {                       "dis" : 117.04699910719626,                       "obj" : {                               "_id" : ObjectId("55ad0e0463ea39b3057bdef0"),                               "onumber" : 2,                               "date" : "2015-07-02",                               "cname" : "zcy",                                "location" : [                                        10,                                        60                               ]                        }                },                {                       "dis" : 206.15528128088303,                       "obj" : {                               "_id" : ObjectId("55ad0e1663ea39b3057bdef1"),                               "onumber" : 3,                               "date" : "2015-07-03",                               "cname" : "zcy",                               "location" : [                                        100,                                        150                               ]                        }                },                {                        "dis" : 269.2582403567252,                       "obj" : {                               "_id" : ObjectId("55ad0e2463ea39b3057bdef2"),                               "onumber" : 4,                               "date" : "2015-07-04",                               "cname" : "zcy",                               "location" : [                                        150,                                        200                               ]                        }                }        ],        "stats" : {               "nscanned" : NumberLong(5),               "objectsLoaded" : NumberLong(5),               "avgDistance" : 136.4921041489609,               "maxDistance" : 269.2582403567252,               "time" : 52        },        "ok" : 1}

 

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 命令,我們可以很好地觀察系統如何使用索引來加快檢索,同時可以針對性最佳化索引。

>db.orders.find({onumber:1}).hint("onumber_1").explain(){       "cursor" : "BtreeCursor onumber_1",       "isMultiKey" : false,       "n" : 1,       "nscannedObjects" : 1,       "nscanned" : 1,       "nscannedObjectsAllPlans" : 1,       "nscannedAllPlans" : 1,       "scanAndOrder" : false,       "indexOnly" : false,       "nYields" : 0,       "nChunkSkips" : 0,       "millis" : 77,       "indexBounds" : {                "onumber" : [                        [                                1,                                1                        ]                ]       },       "server" : "zhengcy-PC:27017",       "filterSet" : false}


 

  對一些比較重要的參數說明:

    1) n:當前查詢返回的文檔數量。

    2)millis:當前查詢所需時間,毫秒數。

   3)indexBounds:當前查詢具體使用的索引。

   4)nscanned:掃描document的行數。

   5)cursor:返回遊標類型(BasicCursor和BtreeCursor),我們這邊使用BtreeCursor類型。

   6)nscannedObjects:被掃描的文檔數量。

   7)scanAndOrder:是否在記憶體中排序。





著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.