文檔是MongoDB中數據的基本單元,很是相似於關係型數據庫管理中的行,但更具表現力。javascript
集合能夠看做是一個擁有動態模式的表。java
MongoDB的一個實例能夠擁有相互獨立的數據庫,每一個數據庫都擁有本身的集合。shell
每一個文檔都有一個特殊的鍵_id
,這個鍵在文檔所屬的集合中是惟一的。數據庫
MongoDB自帶了一個簡單但功能強大的JavaScript shell,可用於管理MongoDB的實例或者數據操做。vim
文檔是MongoDB的核心概念。文檔就是鍵值對的一個有序集。例如在 JavaScript 裏面,文檔就被表示爲對象:服務器
{"greeting": "Hello,World!"}
可是大多數的文檔會被這個簡單的例子複雜的多,一般會表現爲多個鍵/值對:編輯器
{"greeting": "Hello,World!", "foo": 3}
從上面的例子能夠看書,文檔值能夠是多種不一樣的數據類型。分佈式
文檔的鍵是字符串,除了少數的例外狀況。鍵可使用任意 UTF-8 字符。函數
鍵不能含有\0
(空字符),這個字符用於表示鍵的結尾。工具
.
和$
具備特殊的意義,只能在特定的環境下使用。
並且MongoDB不但區分類型,並且區分大小寫,下面的每組的兩個文檔都是不一樣的:
{"foo": 3} {"foo": "3"}
{"foo": 3} {"Foo": 3}
還有一個重要的事情須要注意,就是MongoDB的文檔不能有重複的鍵,例以下面的就是違法的:
{"greenting": "Hello, World!", "greenting": "Hello, MongoDB!"}
集合是動態模式的,因此任何文檔均可以存在同一個集合裏面:
{"greenting": "Hello, World!"} {"foo": 5}
既然集合裏面能夠放置任何文檔,隨之而來的一個問題就是,還有必要使用多個集合嗎:
各類各樣的文檔放到一個集合裏面,對於開發者和管理員來講不方便管理。
在一個集合裏面查詢特定類型的文檔在速度上不划算,分開查詢速度則快得多。
把同種類型的集合放到一個集合裏面,數據會更加集中。
建立索引時,由於一個集合中只放入一種類型的文檔,能夠更加有效的對集合進行索引。
集合名須要時知足下列條件的任意UTF-8字符串:
集合名不能是空字符串("")
集合名不能包含\0
字符
集合名不能以system.
開頭
集合名中不能包含保留字符$
在MongoDB中,多個文檔組成集合,多個集合能夠組成數據庫。
數據庫名必須是知足如下條件的UTF-8字符:
不能是空字符串("")
數據庫名應該區分大小寫,即使是在不區分大小寫的系統也是如此。簡單起見,數據庫名應該所有小寫。
數據庫名最多應爲64字節。
由於數據庫最終會變爲文件系統裏的文件,而數據庫名則就是相應的文件名。這也是數據庫名有這麼多限制的緣由。
可是一些數據庫的名字是保留的,好比admin
,local
,config
。
service mongod start
默認狀況下,MongoDB的監聽端口默認是27017。
mongo
可是這個你要確保你的惡服務器已經啓動了。這樣就會自動進行鏈接MongoDB服務器了。
這個 shell 工具實際上是一個功能完備的 JavaScript 解釋器。能夠運行任意的 JS 程序。
db # 查看當前選擇的數據庫
show dbs # 查看當前服務器的數據庫列表
use footer # 選擇數據庫
當選定數據庫以後,系統會將數據庫鏈接賦值給全局變量db
。這個變量就是經過 shell 訪問 MongoDB 的主要入口點。
例如,經過db.baz
可返回當前數據庫的baz
集合。
post = {"title": "My Blog Post", "content": "Here's my blog post.", "data": new Date()} db.blog.insert(post)
這個插入的數據是一個 JavaScript 對象。它有這麼幾個鍵:title
,content
,date
。在查詢的時候,咱們會看到有一個額外的_id
,這個會在下面進行解釋。
查找多個文檔
db.blog.find()
查找單個文檔
db.blog.findOne()
find
和findOne
都接受一個查詢文檔做爲限定條件。使用find
的時候,shell會自動顯示最多20個匹配的文檔。
例如:給先前的數據增長一個comments
鍵:
post.comment = [] db.blog.update({"title": "My Blog Post"}, post)
update
至少接受兩個參數,第一個參數是限定條件,用於匹配要更新的文檔。第二個是要更新的文檔。
而後咱們在db.blog.find()
就能夠看到新的鍵
使用remove()
方法能夠將文檔從數據庫中永久刪除。可是若是沒有指定任何條件,那麼則會刪除集合內的全部文檔。也能夠接受一個限定條件做爲參數:
db.blog.remove({"title": "My Blog Post"})
如今集合又是空的了。
_id
和 ObejctId
MongoDB中存儲的數據必須有一個_id
鍵。這個鍵的值能夠是任何類型的。默認是一個 Object 對象。在一個集合裏面,每一個文檔都有一個惟一的_id
,相似MySQL的自增ID。
ObejctId
在設計MongoDB的時候,初衷就是用做分佈式數據庫,因此可以在分片的環境中生成惟一的標識符就很是的重要。ObejctId
使用12字節的存儲空間,是一個由24個十六進制數字組成的字符串。
ObjectId的12字節,按照以下方式生成:
前4個字節是從標準紀元開始的時間戳,單位爲秒。由於使用的是當前時間,因此很擔憂是否要對服務器進行時鐘同步。這確實是一個好主意。可是時間戳的實際值並不重要,由於只要它老是不停的增長就行了。
接下來的3個字節是所在主機的惟一標識符。一般是機器主機名的散列值。這樣能夠確保不一樣主機生成不一樣的ObjectId。不產生衝突。
接下來的兩個字節來自產生ObjectId的進程的進程標識符(PID)。
前9個字節保證了同一秒鐘不一樣機器不一樣進程產生的ObjectId是惟一的。最後3字節是一個自動增長的計數器。確保相同進程同一秒產生的ObjectId也是不同的。
_id
若是插入文檔時沒有_id
鍵,系統會幫你自動建立一個。能夠由服務器來作這種事情。可是經過會在客戶端由驅動程序完成。這樣則減輕了數據庫擴展的負擔。
使用下面的方式鏈接到其餘的任何MongoDB實例
mongo host:port/db
這樣就鏈接到host
(IP地址),端口是port
上的db
(此處能夠更換爲你要鏈接的數據庫)了。
這樣啓用以後,就不會鏈接到任何數據庫
mongo --nodb
在啓動以後,可使用new Mongo(hostname)
命令來選擇想要鏈接到的Mongod了。
conn = new Mongo(host:port) db = conn.getDB('db')
執行這些命令以後,就能夠像日常同樣使用db了。
咱們能夠經過下面的功能來查看幫助手冊
help
若是想要知道一個函數是作什麼用的,能夠直接在shell中輸入函數名,可是不要加括號
db.foo.update
好比:
mongo script1.js script2.js script3.js
亦或者:
mongo --quiet host:port/db script1.js script2.js script3.js
--quiet
命令則是讓mongo不要打印"MongoDB shell version ……"的提示了。
或者在交互式shell中運行腳本
load("script1.js")
然而在腳本中,shell輔助函數則是不能使用的。因此咱們須要使用輔助函數對應的JS函數:
輔助函數 | 等價函數 |
---|---|
use foo | db.getSisterDB("foo") |
show dbs | db.getMongo().getDBs() |
show collections | db.getCollectionNames() |
.mongorc.js
文件這個文件會在啓動 shell 時自動運行。通常來講建立此腳本的做用是建立一些本身須要的全局變量,或者爲太長的名字建立比較比較短的別名,或者重寫內置函數,最多見則是移除一些比較「危險」的 shell 內置函數。注意這種方法不能保護數據庫免受惡意用戶的攻擊,只能預防本身的手誤。啓動 mongo時指定--norc
參數,就能夠禁止加載.mongorc.js
var no = function(){ print("Not on my watch"); }; db.dropDatabase = DB.prototype.dropDatabase = no; //禁止刪除數據庫 DBCollection.prototype.drop = no; //禁止刪除集合 DBCollection.prototype.dropIndex = no; //禁止刪除索引
當須要編輯大塊的代碼或者對象的時候,咱們能夠指定編輯器,而後咱們能夠在編輯器內進行編輯:
// .mongorc.js EDITOR = "/usr/bin/vim";
好比在 mongo shell 中:
>var wap = db.books.findOne({title: "War and Peace"}) >edit wap
修改完成以後,保存並退出編輯器。變量就會從新解析而後加載回 shell。