MongoDB(二):基礎知識

MongoDB的基本概念

  1. 文檔是MongoDB中數據的基本單元,很是相似於關係型數據庫管理中的行,但更具表現力。javascript

  2. 集合能夠看做是一個擁有動態模式的表。java

  3. MongoDB的一個實例能夠擁有相互獨立的數據庫,每一個數據庫都擁有本身的集合。shell

  4. 每一個文檔都有一個特殊的鍵_id,這個鍵在文檔所屬的集合中是惟一的。數據庫

  5. MongoDB自帶了一個簡單但功能強大的JavaScript shell,可用於管理MongoDB的實例或者數據操做。vim

文檔

  1. 文檔是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字節。

由於數據庫最終會變爲文件系統裏的文件,而數據庫名則就是相應的文件名。這也是數據庫名有這麼多限制的緣由。
可是一些數據庫的名字是保留的,好比adminlocalconfig

啓動MongoDB服務器

service mongod start

默認狀況下,MongoDB的監聽端口默認是27017。

啓動Mongo客戶端

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 對象。它有這麼幾個鍵:titlecontentdate。在查詢的時候,咱們會看到有一個額外的_id,這個會在下面進行解釋。

查找

查找多個文檔

db.blog.find()

查找單個文檔

db.blog.findOne()

findfindOne都接受一個查詢文檔做爲限定條件。使用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"})

如今集合又是空的了。

_idObejctId

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 shell

使用下面的方式鏈接到其餘的任何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

使用shell執行腳本

好比:

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。

相關文章
相關標籤/搜索