準備工作 繼續連接到mongo 查看資料庫和集合 創建簡單索引 數據準備,在CMD命令視窗中輸入如下初始化腳本: 1、先檢查一下查詢性能 執行如下腳本:var start=new Date()db.books.find({number:20540})var end=new Date()end - s ...
準備工作
繼續連接到mongo
C:\Users\zouqi>mongo MongoDB shell version: 3.0.7 connecting to: test
查看資料庫和集合
> show dbs demo 0.078GB local 0.078GB myDatabase 0.078GB myTest 0.078GB > use myTest switched to db myTest > show collections persons system.indexes
創建簡單索引
數據準備,在CMD命令視窗中輸入如下初始化腳本:
for(var i=0;i<200000;i++){db.books.insert({number:i,name:"book"+i})}
1、先檢查一下查詢性能
執行如下腳本:
var start=new Date()
db.books.find({number:20540})
var end=new Date()
end - start
> db.books.find({number:20540}) { "_id" : ObjectId("5953c63a797216100b773acb"), "number" : 20540, "name" : "book20540" } > var start=new Date() > db.books.find({number:20540}) { "_id" : ObjectId("5953c63a797216100b773acb"), "number" : 20540, "name" : "book20540" } > var end=new Date() > end - start 110
2、為number創建索引
(1代表升序,-1代表降序),在創建索引的時候,由於數據量比較大,會比較耗時,我們會看到執行創建索引腳本的時候,游標會有一定的延時。
> db.books.ensureIndex({number:1}) { "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 } >
3、再執行第一步的代碼可以看出有數量級的性能提升
> var start=new Date() > db.books.find({number:20540}) { "_id" : ObjectId("5953c63a797216100b773acb"), "number" : 20540, "name" : "book20540" } > var end=new Date() > end - start 15 >
之前耗時是110毫秒,創建索引號耗時是15毫秒。
索引使用需要註意的地方
- 創建索引的時候要註意後面參數:1是正序 -1是倒序
- 索引的創建在提高查詢性能的同時會影響插入的性能,對於經常查詢少超入的文檔可以考慮用索引。
- 組合索引要註意索引的先後順序
- 每個鍵都創建索引不一定就能夠提高性能
- 在做排序工作的時候,如果是超大數據量也是可以考慮加上索引用來提高排序的性能。
索引的名稱可以用MongoVUE來查看
創建索引的同時我們還可以指定索引的名字
db.booksensureIndex({name:1},{name:"bookname")
4、唯一索引
如何解決文檔books不能插入重覆的數值?建立唯一索引
db.books.ensureIndex({name:-1},{unique:true})
測試:db.books.insert({name:"hello"})
運行結果如下:
> db.books.insert({name:"hello"}) WriteResult({ "nInserted" : 1 }) > db.books.insert({name:"hello"}) WriteResult({ "nInserted" : 0, "writeError" : { "code" : 11000, "errmsg" : "E11000 duplicate key error index: myTest.books.$name_-1 dup key: { : \"hello\" }" } }) >
5、刪除重覆值
如果創建唯一索引之前已經存在重覆數值該如何處理
db.books.ensureIndex({name:-1},{unique:true,dropDups:true})
6.Hint
如何強制查詢使用指定的索引?
db.books.find({name:"hello",number:1}).hint({name:-1})
註意:指定索引必須是已經創建了的索引
7、Expain
如何詳細查看本次查詢使用哪個索引和查詢數據的狀態信息
db.books.find({name:"hello"}).explain()
> db.books.find({name:"hello"}).explain() { "queryPlanner" : { "plannerVersion" : 1, "namespace" : "myTest.books", "indexFilterSet" : false, "parsedQuery" : { "name" : { "$eq" : "hello" } }, "winningPlan" : { "stage" : "FETCH", "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "name" : 1 }, "indexName" : "bookname", "isMultiKey" : false, "direction" : "forward", "indexBounds" : { "name" : [ "[\"hello\", \"hello\"]" ] } } }, "rejectedPlans" : [ { "stage" : "FETCH", "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "name" : -1 }, "indexName" : "name_-1", "isMultiKey" : false, "direction" : "forward", "indexBounds" : { "name" : [ "[\"hello\", \"hello\"]" ] } } } ] }, "serverInfo" : { "host" : "DESKTOP-V7CFIC3", "port" : 27017, "version" : "3.0.7", "gitVersion" : "6ce7cbe8c6b899552dadd907604559806aa2e9bd" }, "ok" : 1 }
索引管理
1、system.indexes
在shell查看資料庫中已經建立的索引
db.system.indexes.find()
> db.system.indexes.find() { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "myTest.persons" } { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "myTest.books" } { "v" : 1, "key" : { "number" : 1 }, "name" : "number_1", "ns" : "myTest.books" } { "v" : 1, "key" : { "name" : 1 }, "name" : "bookname", "ns" : "myTest.books" } { "v" : 1, "unique" : true, "key" : { "name" : -1 }, "name" : "name_-1", "ns" : "myTest.books" } >
db.system.namespaces.find()
> db.system.namespaces.find() { "name" : "myTest.system.indexes" } { "name" : "myTest.persons" } { "name" : "myTest.persons.$_id_" } { "name" : "myTest.books" } { "name" : "myTest.books.$_id_" } { "name" : "myTest.books.$number_1" } { "name" : "myTest.books.$bookname" } { "name" : "myTest.books.$name_-1" } >
2、後臺執行
執行創建索引的過程中會暫時鎖表,此問題如何解決?
為了不影響查詢,我們可以讓索引的創建過程在後臺執行
db.books.ensureIndex({number:1},{background:true})
3、刪除索引
批量和精確刪除索引
db.runCommand({dropIndexes:"books",index:"name_-1"})
> db.runCommand({dropIndexes:"books",index:"name_-1"}) { "nIndexesWas" : 4, "ok" : 1 } > db.system.indexes.find() { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "myTest.persons" } { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "myTest.books" } { "v" : 1, "key" : { "number" : 1 }, "name" : "number_1", "ns" : "myTest.books" } { "v" : 1, "key" : { "name" : 1 }, "name" : "bookname", "ns" : "myTest.books" } >
db.runCommand({dropIndexes:"books",index:"*"})
> db.runCommand({dropIndexes:"books",index:"*"}) { "nIndexesWas" : 3, "msg" : "non-_id indexes dropped for collection", "ok" : 1 } > db.system.indexes.find() { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "myTest.persons" } { "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "myTest.books" } >
Count&Distinct&Group
1、Count
請查詢persons中美國學生的人數
db.persons.find({country:"USA"}).count()
2、Distinct
請查詢出persons中一共有多少個國家分別是什麼
db.runCommand({distinct:"persons",key:"country"}).values
3、Group
語法:
db.runCommand({group:{
ns:集合名稱,
Key:分組的鍵對象,
Initial:初始化累加器,
$reduce:組分解器,
Condition:條件,
Finalize:組玩傳奇
}})
分組首先會按照key進行分組,每組的每一個文檔都要執行$reduce的方法,它接收2個參數,一個是組內本條記錄,一個是累加器數據。
請查出persons中每隔國家學生數學成績最好的學生信息(必須在90分以上)
db.runCommand({group:{ ns:"persons", key:{"country":true}, initial:{m:0}, $reduce:function(doc,prev){ if(doc.m>prev.m){ prev.m=doc.m; prev.name=doc.name; prev.country=doc.country; } }, condition:{m:{$gt:90}} }})
在上面實例的基礎之上把每個人的信息連接起來寫一個描述賦值到m上
finalize:function(prev){
prev.m=prev.name+"Math scores"+prev.m
}
資料庫命令操作
1、用命令執行一次刪除表操作
db.runCommand({drop:"map"})
2、如何查詢mongoDB為我們提供額命令
db.listCommands()
3、常用命令舉例
查詢伺服器版本號和主機操作系統
db.runCommand({buildInfo:1})
查詢執行集合的詳細信息,大小、空間、索引等
db.runCommand({collStats:"persons"})
查看操作本集合最後一次錯誤信息
db.runCommand({getLastError:"persons"})