程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> mongoDB常見的查詢索引(三)

mongoDB常見的查詢索引(三)

編輯:DB2教程

mongoDB常見的查詢索引(三)


1. _id索引     _id索引是絕大多數集合默認建立的索引     對於每個插入的數據,MongoDB會自動生成一條唯一的_id字段。   > db.jerome_2.collection.insert({x:2}) WriteResult({ "nInserted" : 1 }) > db.jerome_2.collection.getIndexes() [     {         "v" : 1,         "key" : {             "_id" : 1         },         "name" : "_id_",         "ns" : "jerome.jerome_2.collection"     } ] > db.jerome_2.collection.findOne() { "_id" : ObjectId("557004f1f2824fa15224e20b"), "x" : 2 } >    2. 單鍵索引     1.單間索引是最普通的索引     2. 與_id索引不同,單間索引不會自動創建  
> db.jerome_2.collection.ensureIndex({x:1}) # 創建索引
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}
> db.jerome_2.collection.getIndexes()
[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "jerome.jerome_2.collection"
    },
    {
        "v" : 1,
        "key" : {
            "x" : 1
        },
        "name" : "x_1",
        "ns" : "jerome.jerome_2.collection"
    }
]
> db.jerome_2.collection.find({x:1}) #使用創建的索引查詢
{ "_id" : ObjectId("557005a5f2824fa15224e20c"), "x" : 1, "y" : 2, "z" : 3 }
> 

 

3. 多建索引     多鍵索引和單鍵索引創建形式相同,區別在於字段的值。         單鍵索引:值為一個單一的值,例如字符串,數字或者日期。         多鍵索引:值具有多個記錄,例如數組。  
> db.jerome_2.collection.getIndexes()
[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "jerome.jerome_2.collection"
    },
    {
        "v" : 1,
        "key" : {
            "x" : 1
        },
        "name" : "x_1",
        "ns" : "jerome.jerome_2.collection"
    }
]
> db.jerome_2.collection.find()
{ "_id" : ObjectId("557004f1f2824fa15224e20b"), "x" : 2 }
{ "_id" : ObjectId("557005a5f2824fa15224e20c"), "x" : 1, "y" : 2, "z" : 3 }
> db.jeroem_2.collection.insert({x:[1,2,3,4,5]}) #插入一條數組數據,對於這條數據來講,mongodb為其創建了一個多件索引
WriteResult({ "nInserted" : 1 })

 

    4. 復合索引

\

> db.jerome_2.collection.ensureIndex({x:1,y:1}) #創建
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 2,
    "numIndexesAfter" : 3,
    "ok" : 1
}
> db.jerome_2.collection.find({x:1,y:2}) #使用
{ "_id" : ObjectId("557005a5f2824fa15224e20c"), "x" : 1, "y" : 2, "z" : 3 }
> 

 

  5. 過期索引     1. 過期索引:是在一段時間後會過期的索引。     2. 在索引過期後,相應的數據會被刪除     3. 這適合存儲一些在一段時間之後會失效的數據,比如用戶的登陸信息、存儲的日志等。
> db.jerome_2.collection.ensureIndex({time:1},{expireAfterSeconds:30}) #創建過期索引,過期時間30秒
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 3,
    "numIndexesAfter" : 4,
    "ok" : 1
}
> db.jerome_2.collection.insert({time:new Date()}) #插入數據測試
WriteResult({ "nInserted" : 1 })
> db.jerome_2.collection.find()
{ "_id" : ObjectId("557004f1f2824fa15224e20b"), "x" : 2 }
{ "_id" : ObjectId("557005a5f2824fa15224e20c"), "x" : 1, "y" : 2, "z" : 3 }
{ "_id" : ObjectId("55700b17f2824fa15224e20e"), "time" : ISODate("2015-06-04T08:23:51.531Z") }
> db.jerome_2.collection.find()
{ "_id" : ObjectId("557004f1f2824fa15224e20b"), "x" : 2 }
{ "_id" : ObjectId("557005a5f2824fa15224e20c"), "x" : 1, "y" : 2, "z" : 3 }
{ "_id" : ObjectId("55700b17f2824fa15224e20e"), "time" : ISODate("2015-06-04T08:23:51.531Z") }
> db.jerome_2.collection.find() #時間過了就找不到了
{ "_id" : ObjectId("557004f1f2824fa15224e20b"), "x" : 2 }
{ "_id" : ObjectId("557005a5f2824fa15224e20c"), "x" : 1, "y" : 2, "z" : 3 }
> 

 

使用限制     1. 存儲在過期索引字段的值必須是指定的時間類型。(必須是ISODate或者ISODate數組,不能使用時間戳,否則不能被自動刪除)     2. 如果指定了ISODate數組,則按照最小的時間進行刪除。     3. 過期索引不能是復合索引。     4. 刪除時間不是精確的。(刪除過程是由後台程序沒60s跑一次,而且刪除也需要一些時間,所以存在誤差)   6.全文索引 對字符串與字符串數組創建全文可搜索的索引      使用情況:{author:"",titile;"",article:""}   創建方法     1. db.articles.ensureIndex({key:"text"})     2. db.articles.ensureIndex({key_1:"text",key_2:"text"})     3. db.articles.ensureIndex({"$**":"text"}) 使用     1. db.articles.find({$text:{$search:"aa"}})     2. db.articles.find({$text:{$search:"aa bb cc"}}) #空格表示或     3. db.articles.find({$text:{$search:"aa bb -cc"}}) #-cc 表示不包含cc     4. db.articles.find({$text:{$search:"\"aa\" bb cc"}}) #“”,加引號,表示與   例子:
> db.jerome_2.ensureIndex({"article":"text"}) #創建全文索引
{
    "createdCollectionAutomatically" : true,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}
> db.jerome_2.insert({"article":"aa bb cc dd ee"}) #插入測試數據
WriteResult({ "nInserted" : 1 })
> db.jerome_2.insert({"article":"aa bb rr gg zz"})
WriteResult({ "nInserted" : 1 })
> db.jerome_2.insert({"article":"aa bb"})
WriteResult({ "nInserted" : 1 })
> db.jerome_2.insert({"article":"aa bb cc zz ff ww"})
WriteResult({ "nInserted" : 1 })
> db.jerome_2.find({$text:{$search:"aa"}}) #查找
{ "_id" : ObjectId("5572904271c0bbd90f4ce0e2"), "article" : "aa bb rr gg zz" }
{ "_id" : ObjectId("5572903371c0bbd90f4ce0e1"), "article" : "aa bb cc dd ee" }
{ "_id" : ObjectId("5572905671c0bbd90f4ce0e4"), "article" : "aa bb cc zz ff ww" }
{ "_id" : ObjectId("5572904771c0bbd90f4ce0e3"), "article" : "aa bb" }
> db.jerome_2.find({$text:{$search:"ff"}})
{ "_id" : ObjectId("5572905671c0bbd90f4ce0e4"), "article" : "aa bb cc zz ff ww" }
> db.jerome_2.find({$text:{$search:"aa bb cc"}})
{ "_id" : ObjectId("5572904271c0bbd90f4ce0e2"), "article" : "aa bb rr gg zz" }
{ "_id" : ObjectId("5572903371c0bbd90f4ce0e1"), "article" : "aa bb cc dd ee" }
{ "_id" : ObjectId("5572905671c0bbd90f4ce0e4"), "article" : "aa bb cc zz ff ww" }
{ "_id" : ObjectId("5572904771c0bbd90f4ce0e3"), "article" : "aa bb" }
> db.jerome_2.find({$text:{$search:"aa bb -cc"}})
{ "_id" : ObjectId("5572904271c0bbd90f4ce0e2"), "article" : "aa bb rr gg zz" }
{ "_id" : ObjectId("5572904771c0bbd90f4ce0e3"), "article" : "aa bb" }
> db.jerome_2.find({$text:{$search:"\"aa\" \"bb\" \"cc\""}})
{ "_id" : ObjectId("5572903371c0bbd90f4ce0e1"), "article" : "aa bb cc dd ee" }
{ "_id" : ObjectId("5572905671c0bbd90f4ce0e4"), "article" : "aa bb cc zz ff ww" }
> 

 

  全文索引相似度     $meta操作符:{score:{$meta:"textScore"}},卸載查詢條件後面可以反悔返回結果的相似度,與sort一起使用可以達到很好的實用效果。  
> db.jerome_2.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}}) #score越高,相似度越高。
{ "_id" : ObjectId("5572904271c0bbd90f4ce0e2"), "article" : "aa bb rr gg zz", "score" : 1.2 }
{ "_id" : ObjectId("5572903371c0bbd90f4ce0e1"), "article" : "aa bb cc dd ee", "score" : 1.2 }
{ "_id" : ObjectId("5572905671c0bbd90f4ce0e4"), "article" : "aa bb cc zz ff ww", "score" : 1.1666666666666667 }
{ "_id" : ObjectId("5572904771c0bbd90f4ce0e3"), "article" : "aa bb", "score" : 1.5 }
> db.jerome_2.find({$text:{$search:"aa bb"}},{score:{$meta:"textScore"}}).sort({score:{$meta:"textScore"}}) #根據score進行排序
{ "_id" : ObjectId("5572904771c0bbd90f4ce0e3"), "article" : "aa bb", "score" : 1.5 }
{ "_id" : ObjectId("5572903371c0bbd90f4ce0e1"), "article" : "aa bb cc dd ee", "score" : 1.2 }
{ "_id" : ObjectId("5572904271c0bbd90f4ce0e2"), "article" : "aa bb rr gg zz", "score" : 1.2 }
{ "_id" : ObjectId("5572905671c0bbd90f4ce0e4"), "article" : "aa bb cc zz ff ww", "score" : 1.1666666666666667 }
> 

 

    使用限制         1. 每次查詢只能指定一個$text查詢         2. $text查詢不能出現在$nor查詢中         3. 查詢中如果包含了$text,hint不再起作用         4. MongoDB去做你問索引現在還不支持中文   7.地理位置索引 概念:將一些點的位置存儲在MongoDB中,創建索引後,可以按照位置來查找其他點。  分類:     1. 2d索引,用於存儲和查找平面上的點     2. 2dsphere索引,用於存儲和查找球面上的點 查找方式:     1. 查找距離某個點一定距離內的點。     2. 查找包含在某區域內的點。   2d索引 創建:db.location.ensureIndex({"w":"2d"})     位置表示方式:經緯度[經度,緯度]     取值范圍:經度[-180,180] 緯度[-90,90] 查詢方式     1. $near查詢:查詢距離某個點最近的點     2. $geoWithin查詢:查詢某個形狀內的點 1. $near查詢  
> db.location.ensureIndex({"w":"2d"}) #創建2d索引
> db.location.insert({w:[1,1]}) #插入測試數據
WriteResult({ "nInserted" : 1 })
> db.location.insert({w:[1,2]})
WriteResult({ "nInserted" : 1 })
> db.location.insert({w:[2,3]})
WriteResult({ "nInserted" : 1 })
> db.location.insert({w:[100,80]})
WriteResult({ "nInserted" : 1 })
> db.location.find({w:{$near:[1,1]}}) #會返回100個,理你最近的點
{ "_id" : ObjectId("5572a961aba41684d6e8826c"), "w" : [ 1, 1 ] }
{ "_id" : ObjectId("5572a965aba41684d6e8826d"), "w" : [ 1, 2 ] }
{ "_id" : ObjectId("5572a970aba41684d6e8826e"), "w" : [ 2, 3 ] }
{ "_id" : ObjectId("5572a97aaba41684d6e8826f"), "w" : [ 100, 80 ] }
> db.location.find({w:{$near:[1,1],$maxDistance:2}}) #可以使用maxDistance限制(near不能使用minDistance)
{ "_id" : ObjectId("5572a961aba41684d6e8826c"), "w" : [ 1, 1 ] }
{ "_id" : ObjectId("5572a965aba41684d6e8826d"), "w" : [ 1, 2 ] }

 

2. $geoWithin查詢 形狀的表示:     1. $box:矩形,使用{$box:[[<x1>,<y1>],[<x2>,<y2>]]}表示     2. $center:圓形,使用{$center:[[<x1>,<y1>],r]}表示     3. $polygon:多邊形,使用{$polygon:[[<x1>,<y1>],[<x2>,<y2>],[<x3>,<y3>]]}表示 例子:
> db.location.find({w:{$geoWithin:{$box:[[0,0],[3,3]]}}}) #矩形
{ "_id" : ObjectId("5572a965aba41684d6e8826d"), "w" : [ 1, 2 ] }
{ "_id" : ObjectId("5572a970aba41684d6e8826e"), "w" : [ 2, 3 ] }
{ "_id" : ObjectId("5572a961aba41684d6e8826c"), "w" : [ 1, 1 ] }
> db.location.find({w:{$geoWithin:{$box:[[1,2],[2,3]]}}})
{ "_id" : ObjectId("5572a965aba41684d6e8826d"), "w" : [ 1, 2 ] }
{ "_id" : ObjectId("5572a970aba41684d6e8826e"), "w" : [ 2, 3 ] }
> db.location.find({w:{$geoWithin:{$center:[[0,0],100]}}}) #圓形,100是半徑
{ "_id" : ObjectId("5572a961aba41684d6e8826c"), "w" : [ 1, 1 ] }
{ "_id" : ObjectId("5572a970aba41684d6e8826e"), "w" : [ 2, 3 ] }
{ "_id" : ObjectId("5572a965aba41684d6e8826d"), "w" : [ 1, 2 ] }
> db.location.find({w:{$geoWithin:{$center:[[0,0],1000]}}})
{ "_id" : ObjectId("5572a961aba41684d6e8826c"), "w" : [ 1, 1 ] }
{ "_id" : ObjectId("5572a97aaba41684d6e8826f"), "w" : [ 100, 80 ] }
{ "_id" : ObjectId("5572a970aba41684d6e8826e"), "w" : [ 2, 3 ] }
{ "_id" : ObjectId("5572a965aba41684d6e8826d"), "w" : [ 1, 2 ] }
> db.location.find({w:{$geoWithin:{$polygon:[[0,0],[0,1],[2,5],[6,1]]}}}) #多邊形查詢(各個點圍成的多邊形的范圍)
{ "_id" : ObjectId("5572a970aba41684d6e8826e"), "w" : [ 2, 3 ] }
{ "_id" : ObjectId("5572a961aba41684d6e8826c"), "w" : [ 1, 1 ] }
{ "_id" : ObjectId("5572a965aba41684d6e8826d"), "w" : [ 1, 2 ] }
> db.location.find({w:{$geoWithin:{$polygon:[[0,0],[0,1],[2,5],[6,1000],[1001,0]]}}})
{ "_id" : ObjectId("5572a970aba41684d6e8826e"), "w" : [ 2, 3 ] }
{ "_id" : ObjectId("5572a97aaba41684d6e8826f"), "w" : [ 100, 80 ] }
{ "_id" : ObjectId("5572a961aba41684d6e8826c"), "w" : [ 1, 1 ] }
{ "_id" : ObjectId("5572a965aba41684d6e8826d"), "w" : [ 1, 2 ] }

 

  3. 使用geoNear查詢 geoNear使用runCommand命令進行使用
db.runCommand(
    {getNear:<collection>,
    near:[x,y],
    minDistance:(對2d索引無效)
    maxDistance:
    num:
}
)

> db.runCommand({geoNear:"location",near:[1,2],maxDistance:10,num:1})
{
    "results" : [
        {
            "dis" : 0,
            "obj" : {
                "_id" : ObjectId("5572a965aba41684d6e8826d"),
                "w" : [
                    1,
                    2
                ]
            }
        }
    ],
    "stats" : {
        "nscanned" : NumberLong(1),
        "objectsLoaded" : NumberLong(1),
        "avgDistance" : 0,
        "maxDistance" : 0,
        "time" : 2
    },
    "ok" : 1
}
> 

 

  球面地理位置索引 概念:球面地理位置索引 創建方式:db.collection.ensureIndex({w:"2dsphere"}) 位置表示方式: GeoJson:描述一個點,一條直線,多邊形等形狀 格式:{type:"",coordinates:[<coordinates>]} 支持$minDistance與$maxDistance   創建索引比較重要屬性介紹 格式     db.collection.ensureIndex({param},{param}) #第二個參數是索引的屬性   比較重要的屬性有:名字、唯一性、稀疏性、是否定時刪除。   1. 名字,name指定:db.collection.ensureIndex({},{name:""})     默認命名格式是如下這樣的     單鍵索引,1和-1,命名是根據key+_1/-1
> db.jerome_2.ensureIndex({x:1})
> db.jerome_2.ensureIndex({y:-1})
> db.jerome_2.getIndexes()
[
    {
        "v" : 1,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "jerome.jerome_2"
    },
    {
        "v" : 1,
        "key" : {
            "x" : 1
        },
        "name" : "x_1",
        "ns" : "jerome.jerome_2"
    },
    {
        "v" : 1,
        "key" : {
            "y" : -1
        },
        "name" : "y_-1",
        "ns" : "jerome.jerome_2"
    }

 

      復合索引  
> db.jerome_2.ensureIndex({x:1,y:-1})
> db.jerome_2.ensureIndex({x:1,y:-1,z:1})
> db.jerome_2.getIndexes()
[
    {
        "v" : 1,
        "key" : {
            "x" : 1,
            "y" : -1
        },
        "name" : "x_1_y_-1",
        "ns" : "jerome.jerome_2"
    },
    {
        "v" : 1,
        "key" : {
            "x" : 1,
            "y" : -1,
            "z" : 1
        },
        "name" : "x_1_y_-1_z_1",
        "ns" : "jerome.jerome_2"
    }
]
mongodb對索引限制是125字節,所以我們需要自定義索引名字。  
> db.jerome_2.ensureIndex({x:1,y:1,z:1,m:1},{name:"normal_index"})
> db.jerome_2.getIndexes()
[
    {
        "v" : 1,
        "key" : {
            "x" : 1,
            "y" : 1,
            "z" : 1,
            "m" : 1
        },
        "name" : "normal_index",
        "ns" : "jerome.jerome_2"
    }
]
> db.jerome_2.dropIndex("normal_index")
{ "nIndexesWas" : 7, "ok" : 1 }
> 

 

  2. 唯一性,unique指定:db.collection.ensureIndex({},{unique:true/false})
> db.jerome.ensureIndex({m:1,n:1},{unique:true})
{
    "createdCollectionAutomatically" : true,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}
> db.jerome.insert({m:1,n:2})
WriteResult({ "nInserted" : 1 })
> db.jerome.insert({m:1,n:2})
WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 11000,
        "errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: jerome.jerome.$m_1_n_1  dup key: { : 1.0, : 2.0 }"
    }
})
> 

 

3. 稀疏性,sparse指定:db.collection.ensureIndex({},{sparse:true/false}) 默認創建的索引是不稀疏的。 因為MongoDB沒有固定的格式,插入的時候可能插入不存在的字段,比如x:1,MongoDB會為這條不存在的字段創建索引,如果不希望發現這樣的事情可以指定稀疏索引為true,就不會為不存在的字段創建索引了。可以減少磁盤暫用和增大插入速度。  
> db.jerome.insert({"m":1})
WriteResult({ "nInserted" : 1 })
> db.jerome.insert({"n":1})
WriteResult({ "nInserted" : 1 })
> db.jerome.find({m:{$exists:true}}) #exists查找數據集合中一個字段存在或者不存在的記錄
{ "_id" : ObjectId("55729ec1aba41684d6e8826a"), "m" : 1 }
{ "_id" : ObjectId("55729d5caba41684d6e88268"), "m" : 1, "n" : 2 }
> db.jerome.ensureIndex({m:1},{sparse:true}) #創建稀疏索引
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 2,
    "numIndexesAfter" : 3,
    "ok" : 1
}
> db.jerome.find({m:{$exists:false}}) #MongoDB內部問題,所以找得到,通過下面強制指定索引
{ "_id" : ObjectId("55729ec7aba41684d6e8826b"), "n" : 1 }
> db.jerome.find({m:{$exists:false}}).hint("m_1") #下面這條記錄,不存在m字段,所以不會創建索引,所以查不到記錄 
> 

 

注意:不能在稀疏索引上查找這個字段不存在的記錄。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved