本章承諾過要通過JavaScript Shell來介紹MongoDB。你已經瞭解了數據操作和索引的基本知識,這裡我將介紹一些技術,幫助你獲得mongod
進程的信息。舉例來說,你可能想知道眾多集合一共佔用了多少空間,或者你在一個集合上定義了多少索引。此處詳述的命令能幫助你診斷性能問題並監控數據。
我們還會瞭解MongoDB的命令界面。大多數能在MongoDB實例上執行的特殊非CRUD操作——從服務器狀態檢查到數據文件完整性校驗——都是由數據庫命令實現的。我將說明MongoDB上下文裡的命令,並演示其易用性。最後,知道如何尋求幫助總是好的,所以我將指出在Shell裡怎麼獲得幫助,以幫助你進一步瞭解MongoDB。
2.3.1 獲取數據庫信息
你經常想知道指定實例上到底有哪些集合與數據庫,幸運的是MongoDB Shell提供了許多命令和語法糖,以此能獲取系統相關的信息。
show dbs
顯示了系統上所有數據庫的列表:
> show dbs admin local test tutorial
show collections
顯示了定義在當前數據庫裡的所有集合的列表。1如果目前還是選中了tutorial
數據庫,你會看到之前用過的集合:
1. 還可以鍵入範圍更明確的show tables
。
> show collections numbers system.indexes users
你可能會對其中的system.indexes
集合感到陌生。這是存在於每個數據庫中的特殊集合,其中每一項都定義了數據庫的一個索引。我們能直接查詢該集合,但這樣的輸出不易閱讀,還是像我們之前看到的那樣,使用getIndexes
方法更好一些。
為了獲得數據庫與集合更底層的信息,stats
方法非常有用。在數據庫對像上執行該方法時,會獲得如下輸出:
> db.stats { "collections" : 4, "objects" : 200012, "dataSize" : 7200832, "storageSize" : 21258496, "numExtents" : 11, "indexes" : 3, "indexSize" : 27992064, "ok" : 1 }
我們還可以在單獨的集合上執行stats
命令:
> db.numbers.stats { "ns" : "tutorial.numbers", "count" : 200000, "size" : 7200000, "storageSize" : 21250304, "numExtents" : 8, "nindexes" : 2, "lastExtentSize" : 10066176, "paddingFactor" : 1, "flags" : 1, "totalIndexSize" : 27983872, "indexSizes" : { "_id_" : 21307392, "num_1" : 6676480 }, "ok" : 1 }
結果文檔中的一些值僅在複雜的調試情況中才會有用。但最起碼能知道指定集合和它的索引到底佔用了多少空間。
2.3.2 命令工作原理
與截至目前本章所描述的插入、更新、刪除和查詢操作不同,某些MongoDB操作是數據庫命令。數據庫命令一般都是管理類命令,比如之前提到的stats
方法,但它們也可能用於控制諸如MapReduce之類的核心MongoDB特性。
不管這些命令的功能是什麼,它們的共同點是,在實現上它們都是對名為$cmd
的特殊虛集合的查詢。要明白這是什麼意思,來看一個簡單的例子。還記得我們是如何調用stats
數據庫命令的嗎:
> db.stats
stats
是一個輔助方法,它封裝了Shell的命令調用方法。可以輸入下列等效操作:
> db.runCommand( {dbstats: 1} )
該操作的輸出和stats
方法的輸出是一樣的。請注意,命令是由文檔{dbstats: 1}
來定義的。一般來說,我們可以向runCommand
方法傳遞文檔定義,借此運行各種命令。下面是運行集合統計命令的方法:
> db.runCommand( {collstats: 'numbers'} )
命令的輸出你一定不會陌生。
要深入瞭解數據庫命令,我們應該看看runCommand
方法到底是怎麼工作的。這並不難知道,因為MongoDB Shell會輸出所有方法的實現,只要這些方法忽略括號就行了。我們可以改變下面的命令:
> db.runCommand
執行無括號的版本,一探究竟:
> db.runCommand function (obj) { if (typeof obj == "string") { var n = {}; n[obj] = 1; obj=n; } return this.getCollection("$cmd").findOne(obj); }
函數中的最後一行無非就是查詢$cmd
集合。給它下個恰當的定義,數據庫命令是對特殊集合$cmd
的查詢,查詢選擇器就是對命令本身的定義,僅此而已。你能想到如何手工運行集合統計命令嗎?這很簡單:
db.$cmd.findOne( {collstats: 'numbers'} );
使用runCommand
輔助方法會更簡單一點,但能瞭解內部細節總是好的。