MongoDB 第3章 MongoDB快速入門
MongoDB shell是MongoDB自帶的交互式JavaScript shell,用來對MongoDB進行操作和管理的交互式環境。
使用./mongo --help可以查看相關連接參數,下面將從常見的操作,如插入、查詢、修改、刪除等幾個方面闡述MongoDB shell的用法。
1.1、啟動數據庫
MongoDB安裝、配置完后,必須先啟動它,然后才能使用它,怎么啟動它呢?下面分別展示了3種方式啟動實例。
1.1.1、命令行方式啟動
MongoDB默認存儲數據目錄為/data/db/(或者C:\data\db),默認端口為27017,默認HTTP端口為28017,當然你也可以修改成不同目錄,只需要指定dbpath參數:
./mongod --dbpath=/var/mongodb/data/ --logpath /var/mongodb/logs/log.log -fork
說明:--fork表示后臺進程啟動。
1.1.2、配置文件方式啟動
如果是一個專業的DBA,那么實例啟動時會添加很多的參數以便使系統運行的非常穩定,這樣就可以會在啟動時在mongod后面加一長串的參數,看起來非常混亂而且不好管理和維護,那么有什么辦法讓這些參數有條理呢?MongoDB也支持同mysql一樣的讀取啟動配置文件的方式來啟動數據庫,配置文件的內容如下:
[root@localhost bin]# vi /etc/mongodb.cnf
dbpath=/var/mongodb/data/
啟動時加上-f參數,并指向配置文件即可
[root@localhost bin]# ./mongod -f /etc/mongodb.cnf
1.1.3、Daemon方式啟動
大家可以注意到上面的兩種方式都在前臺啟動MongDB進程,但當啟動MongoDB進程的session窗口不小心關閉時,MongoDB進程也將隨之停止,這樣無疑是非常不安全的,幸好MongoDB提供了一種后臺Daemon方式啟動的選擇,只需要加上一個--fork參數即可,這就使得我們可以更方便的操作數據庫的啟動,但如果用到了--fork參數就必須也啟動--logpath參數,這是強制的。
./mongod --dbpath=/var/mongodb/data/ --logpath /var/mongodb/logs/log.log -fork
沒有--logpath參數,則會提示:--fork has to be used with --logpath
1.1.4、MongoDB參數說明
最簡單的、通過執行mongod即可啟動MongoDB數據庫服務,mongod支持很多的參數,但都有默認值,其中最重要的是需要制定數據文件路徑,或者確保默認的/data/db/存在并且具有訪問權限,否則啟動后會自動關閉服務,那也就是說,只要確保dbpath就可以啟動MongoDB服務了。
mongod的主要參數有:
dbpath:數據文件存放路徑,每個數據庫會在啟動創建一個子目錄,用于防止同一個實例多次運行的mongod.lock也保存在此目錄中。
logpath:錯誤日志文件。
logappend:錯誤日志采用追加模式(默認是覆寫模式)
bind_ip:對外服務的綁定ip,一般設置為空,以及綁定在本機所有可用ip上,如有需要可以單獨制定。
port:對外服務端口,web管理端口在這個port的基礎上+1000。
fork:以后臺Daemon形式運行服務。
journal:開啟日志功能,通過保存操作日志類降低單機故障的恢復時間,在1.8版本后正式加入,取代在1.7.5版本中的dur參數。
syncdelay:系統同步刷新磁盤的時間,單位為秒,默認是60秒。
directoryperdb:每個db存放在單獨的目錄中,建議設置該參數,域MySQL的獨立表空間類似。
maxConns:最大連接數。
repairpath:執行repair時的臨時目錄,在如果沒有開啟joural,異常down機后重啟,必須執行repair操作。
在源代碼中,mongod的參數分為一般參數,windows參數,replication參數,replica set參數,以及隱含參數,上面列舉了的都是一般參數,如果要配置replication、replica set等,還需要設置對應的參數,這里先不展開,后續會有專門的章節來講述,執行mongod --help可以看到對大多數參數的解釋,但又一些隱含參數,則只能通過看帶來獲得(見db.cpppo::options_description hidden_options("Hidden options");),隱含參數一般要么是還在開發中,要么是準備廢棄,因此在生產環境中不建議使用。
可能你已經注意到,mongod的參數中,沒有設置內存大小相關的參數,是的,MongoDB使用os mmap機制來緩存數據文件數據,自身目前不提供緩存機制,這樣好處是代碼簡單,mmap在數據量不超過內存時效率很高,但是數據超過系統可用內存后,則寫入的性能可能不太穩定,容易出現大起大落 ,不過在最新的1.8版本中,這個情況相對以前的版本已經有了一定程度的改善。
這么多參數,全面寫在命令行中則容易雜亂而不好管理,因此mongod支持將參數寫入到一個配置文本文件中,然后通過config參數來引用此配置文件:
./mongod --config /etc/mongo.cnf
1.2、停止數據庫
MongoDB提供的停止數據庫命令也非常豐富,如果Control-C、發送shutdownServer()指定以及發送Unix系統中斷信號等。
1.2.1、Control-C
如果處理連接狀態,那么直接可以通過Control-C的方式去停止MongoDB實例,具體如下:
[root@localhost bin]# ./mongo
MongoDB shell version: 2.6.6
connecting to: test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
> ^C
bye
[root@localhost bin]#
1.2.2、shutdownServer()指令
如果處理連接狀態,那么直接可以通過admin庫中發送db.shutdownServer()指令去停止MongoDB實例,具體如下:
[root@localhost bin]# ./mongo
MongoDB shell version: 2.6.6
connecting to: test
> use admin
switched to db admin
> db.shutdownServer()
2015-01-04T10:23:44.506+0800 DBClientCursor::init call() failed
server should be down...
2015-01-04T10:23:44.519+0800 trying reconnect to 127.0.0.1:27017 (127.0.0.1) failed
2015-01-04T10:23:44.521+0800 warning: Failed to connect to 127.0.0.1:27017, reason: errno:111 Connection refused
2015-01-04T10:23:44.521+0800 reconnect 127.0.0.1:27017 (127.0.0.1) failed failed couldn't connect to server 127.0.0.1:27017 (127.0.0.1), connection attempt failed
>
1.2.3、Unix系統指令
在找到實例的進程后,可能通過發送kill -2 PID或者kill -15 PID來停止進程,具體如下:
[root@localhost bin]# ps aux|grep mongod
root ? ? ?2676 ?1.4 ?3.0 467208 30668 ? ? ? ? ?Sl ? 10:24 ? 0:00 ./mongod --dbpath=/var/mongodb/data/ --logpath /var/mongodb/logs/log.log -fork
root ? ? ?2695 ?0.0 ?0.0 103236 ? 864 pts/1 ? ?S+ ? 10:24 ? 0:00 grep mongod
注意:不要使用kill -9 PID來殺死MongoDB進程,這樣可以會導致MongoDB的數據損壞。
[root@localhost bin]# kill -2 2676
1.3、連接數據庫
現在我們就可以使用自帶的MongoDB shell工具來操作數據庫了,我們也可以使用各種編程語言的驅動來使用MongDB,但自帶的MongoDB shell工具可以方便我們管理數據庫,新打開一個Session輸入:/usr/local/mongodb/bin/mongo,如果出現下面提示,那么你就說明連接上數據庫了,可以進行操作了。
[root@localhost bin]# ./mongo
MongoDB shell version: 2.6.6
connecting to: test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
>
默認shell連接的是本機的localhost上面的test庫,"connection to:"這個會顯示你正在使用的數據庫名稱,想換數據庫的話可以用use mydb來實現。
1.4、插入記錄
下面我們來建立一個test的集合并寫入一些數據,建立兩個對象j和t,并保存到集合中區,在例子里">"來表示用shell輸入提示符。
> a={name:"mongo"}
{ "name" : "mongo" }
> b={x:4}
{ "x" : 4 }
> db.xuz.save(a)
WriteResult({ "nInserted" : 1 })
> db.xuz.save(b)
WriteResult({ "nInserted" : 1 })
> db.xuz.find();
{ "_id" : ObjectId("54a8a4ff2db3e1b27d0e5203"), "name" : "mongo" }
{ "_id" : ObjectId("54a8a5042db3e1b27d0e5204"), "x" : 4 }
說明:
不需要預先創建一個集合,在第一次插入數據時會自動創建。
在文檔中其實可以存儲任何結構的數據,當然在實際應用我們存儲的還是相同類型文檔的集合,這個特性其實可以在應用里很靈活,你不需要類似alter table語句來修改你的數據結構。
每次插入數據時候集合中會有一個ID,名字叫_id。
下面再添加一些數據:
> for(var i=1;i<=50;i++) db.xuz.save({x:5,j:i});
WriteResult({ "nInserted" : 1 })
> db.xuz.find();
{ "_id" : ObjectId("54a8a4ff2db3e1b27d0e5203"), "name" : "mongo" }
{ "_id" : ObjectId("54a8a5042db3e1b27d0e5204"), "x" : 4 }
{ "_id" : ObjectId("54a8a5a427681683ca2c2466"), "x" : 5, "j" : 1 }
{ "_id" : ObjectId("54a8a5a427681683ca2c2467"), "x" : 5, "j" : 2 }
{ "_id" : ObjectId("54a8a5a427681683ca2c2468"), "x" : 5, "j" : 3 }
{ "_id" : ObjectId("54a8a5a427681683ca2c2469"), "x" : 5, "j" : 4 }
{ "_id" : ObjectId("54a8a5a427681683ca2c246a"), "x" : 5, "j" : 5 }
{ "_id" : ObjectId("54a8a5a427681683ca2c246b"), "x" : 5, "j" : 6 }
{ "_id" : ObjectId("54a8a5a427681683ca2c246c"), "x" : 5, "j" : 7 }
{ "_id" : ObjectId("54a8a5a427681683ca2c246d"), "x" : 5, "j" : 8 }
{ "_id" : ObjectId("54a8a5a427681683ca2c246e"), "x" : 5, "j" : 9 }
{ "_id" : ObjectId("54a8a5a427681683ca2c246f"), "x" : 5, "j" : 10 }
{ "_id" : ObjectId("54a8a620e708df7187eb2dd8"), "x" : 5, "j" : 1 }
{ "_id" : ObjectId("54a8a620e708df7187eb2dd9"), "x" : 5, "j" : 2 }
{ "_id" : ObjectId("54a8a620e708df7187eb2dda"), "x" : 5, "j" : 3 }
{ "_id" : ObjectId("54a8a620e708df7187eb2ddb"), "x" : 5, "j" : 4 }
{ "_id" : ObjectId("54a8a620e708df7187eb2ddc"), "x" : 5, "j" : 5 }
{ "_id" : ObjectId("54a8a620e708df7187eb2ddd"), "x" : 5, "j" : 6 }
{ "_id" : ObjectId("54a8a620e708df7187eb2dde"), "x" : 5, "j" : 7 }
{ "_id" : ObjectId("54a8a620e708df7187eb2ddf"), "x" : 5, "j" : 8 }
Type "it" for more
說明:請注意這里循環次數是50,但是只顯示到第20條,還有其他數據沒有顯示出來,如果想繼續查詢下面的數據只需要使用it命令,就會繼續顯示下面的數據:
> it
{ "_id" : ObjectId("54a8a620e708df7187eb2de0"), "x" : 5, "j" : 9 }
{ "_id" : ObjectId("54a8a620e708df7187eb2de1"), "x" : 5, "j" : 10 }
{ "_id" : ObjectId("54a8a620e708df7187eb2de2"), "x" : 5, "j" : 11 }
{ "_id" : ObjectId("54a8a620e708df7187eb2de3"), "x" : 5, "j" : 12 }
{ "_id" : ObjectId("54a8a620e708df7187eb2de4"), "x" : 5, "j" : 13 }
{ "_id" : ObjectId("54a8a620e708df7187eb2de5"), "x" : 5, "j" : 14 }
{ "_id" : ObjectId("54a8a620e708df7187eb2de6"), "x" : 5, "j" : 15 }
{ "_id" : ObjectId("54a8a620e708df7187eb2de7"), "x" : 5, "j" : 16 }
{ "_id" : ObjectId("54a8a620e708df7187eb2de8"), "x" : 5, "j" : 17 }
{ "_id" : ObjectId("54a8a620e708df7187eb2de9"), "x" : 5, "j" : 18 }
{ "_id" : ObjectId("54a8a620e708df7187eb2dea"), "x" : 5, "j" : 19 }
{ "_id" : ObjectId("54a8a620e708df7187eb2deb"), "x" : 5, "j" : 20 }
{ "_id" : ObjectId("54a8a621e708df7187eb2dec"), "x" : 5, "j" : 21 }
{ "_id" : ObjectId("54a8a621e708df7187eb2ded"), "x" : 5, "j" : 22 }
{ "_id" : ObjectId("54a8a621e708df7187eb2dee"), "x" : 5, "j" : 23 }
{ "_id" : ObjectId("54a8a621e708df7187eb2def"), "x" : 5, "j" : 24 }
{ "_id" : ObjectId("54a8a621e708df7187eb2df0"), "x" : 5, "j" : 25 }
{ "_id" : ObjectId("54a8a621e708df7187eb2df1"), "x" : 5, "j" : 26 }
{ "_id" : ObjectId("54a8a621e708df7187eb2df2"), "x" : 5, "j" : 27 }
{ "_id" : ObjectId("54a8a621e708df7187eb2df3"), "x" : 5, "j" : 28 }
Type "it" for more
從技術上講find()返回一個游標對象,但在上面的例子里,并沒有拿到一個游標的變量,所以shell自動遍歷游標,返回一個初始化的set,并允許我們繼續用it迭代輸出,當然我們也可以直接用游標輸出,不過這個事游標部分的內容了。
1.5、_id key
MongoDB支持的數據類型中,_id是其自身產物,下面對其做些簡單的介紹。
存儲在MongoDB集合中的每個文檔(document)都有一個默認的主鍵_id,這個主鍵名稱是固定的,它可以使MongoDB支持的任何數據類型,默認是ObjectId,在關系數據庫schema設計中,主鍵大多是數值型的,比如常用的int和long,并且更通暢的是主鍵的取值由數據庫自增獲得,這種主鍵數值的有序性有時也標明了某種邏輯,反觀MongoDB,它設計之初就定位于分布式存儲系統,所以它原生的不支持自增主鍵。
_id key舉例說明:
當我們在往一個集合中寫入一條文檔時,系統會自動生成一個名為_id的key,如:
> db.xuz.find();
{ "_id" : ObjectId("54a8a4ff2db3e1b27d0e5203"), "name" : "mongo" }
{ "_id" : ObjectId("54a8a5042db3e1b27d0e5204"), "x" : 4 }
這里多出了一個類型為ObjectId的key,在插入的時候并沒有指定,這有點類似Oracle的rowid的信息,屬于自動生成的。
在MongoDB中,每一個集合都必須有一個叫做_id的字段,字段類型默認是ObjectId,換句話說,字段類型可以不是ObjectId,比如:
{ "_id" : ObjectId("54a8a621e708df7187eb2e08"), "x" : 5, "j" : 49 }
{ "_id" : ObjectId("54a8a621e708df7187eb2e09"), "x" : 5, "j" : 50 }
{ "_id" : 3, "name" : "zhangsan" }
雖然_id的類型可以自由指定,但是在同一個集合中必須唯一,如果插入重復的值的話,系統將會拋出異常,具體如下:
> db.xuz.insert({_id:3,"name":zhaoliu});
2015-01-04T10:41:26.289+0800 ReferenceError: zhaoliu is not defined
> db.xuz.insert({_id:3,"name":"zhaoliu"});
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: test.xuz.$_id_ ?dup key: { : 3.0 }"
}
})
說明:因為前面已經插入一條_id=3的記錄,所以再插入相同的文檔就不允許了。
MongoDB 數據庫
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。