1.使用shell的技巧
shell內建的協助:
使用db.help()可以查看資料庫層級的命令協助,集合的相關協助可以通過db.blog.help()
輸入的時候不要輸入括弧,這樣就可以顯示該函數的javascript原始碼:
使用db.集合名 的方式來訪問集合一般不會有問題,但如果集合名恰好是資料庫類的一個屬性,這樣會有問題,例如:
要訪問version這個集合,使用db.version是不行的,因為db.version是個資料庫函數.
當javascript只有在db中找不到指定的屬性時,才會將其作為集合返回.當有屬性與目的地組合約名時,可以使用
getCollection函數,如:db.getCollection("version")
要查看名稱中含有無效的javascript字元的集合,如:db.blog-refactor是個有效集合名,但在javascript中就變成了
變數相減.通過db.getCollection("blog-refactor")可以得到blog-refactor集合.
在javascript中,x.y和x['y']是等價的.
var collections={"posts","comments","authors"};
for(i in collections)
{
doStuff(db.blog[collections[i]])
}
而不是寫成這樣:
doStuff(db.blog.posts)
doStuff(db.blog.comments)
doStuff(db.blog.authors)
2.資料類型
基本的資料類型
MongoDB的文檔類似於JSON.在概念上與javascript中的對象相似.
MongoDB在保留JSON基本的索引值對特性的基礎上,添加了其他一些資料類型.
1.null
表示空值或者不存在的欄位
{"x":null}
2.布爾值
true或false
{"x":false}
3.32位整數
shell中這個類型不適用,因為javascript只支援64位浮點數,所以32位整數會被自動轉換
4.64位整數
shell中這個類型不適用,shell會使用一個特殊的內嵌文檔來顯示64位整數
5.64位浮點數
shell中的數字都是這種類型,下面都是浮點數
{"x":3.14}
{"x":3}
6.字串
utf-8字串都可表示為字串類型的資料
{"x":"Refactor"}
7.符號
shell中這個類型不適用.shell將資料庫裡的符號類型轉換成字串
8.對象id
對象id是文檔的12位元組的唯一ID
{"x":ObjectId()}
9.日期
日期類型儲存的是從標準紀元開始的毫秒數.不儲存時區
{"x":new Date()}
10.Regex
文檔中可以包含Regex,採用javascript文法
{"x":/refactor/i}
11.代碼
文檔中可以包含javascript代碼
{"x":function(){....}}
12.位元據
位元據由任意位元組的串組成,shell中不能用
13.最大值
BSON包含的特殊類型,表示可能的最大值,shell中不能用
14.最小值
BSON包含的特殊類型,表示可能的最小值,shell中不能用
15.未定義
文檔中可以使用未定義類型
{"x":undefined}
16.數組
值的集合或列表可以表示成數組
{"x":["a","b","c"]}
17.內嵌文檔
文檔中可以包含別的文檔,也可以作為值嵌入到父文檔中
{"x":{"hello":"world"}}
數字類型
javascript中只有一個"數字"類型.MongoDB中有3種數字類型(32位整數,64位整數,64位浮點數),
shell必須繞過javascript的限制.預設情況下,shell中的數字都被MongoDB當成雙精確度數.這就意味著
如果你從資料庫中獲得的是一個32位整數,修改文檔後,將文檔存回到資料庫的時候,這個整數就被轉換成了
浮點數,即便是保持這個整數不修改,也會轉換為浮點數.所以不應該子啊shell下覆蓋整個文檔.
數字只能表示為雙精確度數(64位浮點數)的另外一個問題是:有些64位整數並不能表示為64為浮點數,所以要存入
一個64位整數,在shell中查看,它會表示為一個內嵌文檔,表示可能不準確.
日期類型
在javascript中,Date對象用作MongoDB的日期類型,建立一個新的Date對象,通常會調用new Date(),而不是 Date()
調用建構函式(不包括new)實際會返回對日期的字串表示,而不是真正的Date對象,這是javaScript本身的特性.
shell中的日期顯示時使用本地時區設定.但是,日期在資料中是從標準紀元開始的毫秒數的形式儲存的,沒有與之相關的時區資訊
數群組類型
數組是一組值,既可以作為有序對象(如:列表,棧或隊列)來操作,也可以作為無序對象(如:集合)操作.
如:{"things":["pie",3.14]}
訴諸數組可以包含不同資料類型的元素(這個例子中是一個字串和一個浮點數),實際上,常規索引值對支援的值都可以
作為數組的元素,甚至是嵌套的數組
MongoDB可以查詢所有"things"數組中還有3.14的文檔,要是經常使用這個查詢,可以對"things"建立索引,來提高效能
MongoDB可以使用原子更新修改數組中的內容,比如深入數組內部將pie改為pi.
內嵌文件類型
內嵌文檔就是把整個MongoDB文檔作為另一個文檔中鍵的一個值.這樣資料可以組織的更自然,不用非得存成扁平結構.
如:應一個文檔來表示一個人,同時還要儲存他的地址,可以將地址內嵌到文檔中
peopleAddress=
{
"name":"Refactor",
"address":
{
"street":"wuzhong",
"city":"suzhou"
}
}
同數組一樣,MongoDB能夠理解內嵌文檔的結構,並能深入其中 構建索引,執行查詢或更新.
內嵌文檔可以改變處理資料的方式,在關係型資料庫中,之前的文檔一般會拆分成兩個表("people"和"address")
中的兩個行.在MongoDB中,可以將地址文檔直接嵌入到人員文檔中.這樣也有壞處,因為MongoDB會儲存很多
的重複資料,如果在關係型資料庫中"address"在一個獨立的表中,要修改地址中的拼字錯誤.當我們對"address"表
進行修改後,那麼每一個使用這個地址的人的資訊都會得到更新.但在MongoDB中,則需要在每個人的文檔中修改拼字錯誤
_id和ObjectId
MongoDB中儲存的文檔必須有一個"_id"鍵.這個鍵的值可以是任何類型,預設是ObjectId對象.
在一個集合裡面,每個文檔都有唯一的"_id"值,來確保集合裡面每個文檔都能唯一的標識.如果有
兩個集合的話,兩個集合可以都有一個值為123的"_id"鍵,但是每個集合裡面只能有一個"_id"是123的文檔
ObjectId是"_id"的預設類型,ObjectId可以確保分布式資料的唯一性
如果在插入文檔的時候沒有"_id"鍵,系統會自動幫你建立一個.可以由MongoDB伺服器來做這件事情,
但通常會在用戶端驅動程式完成,理由如下:
1.雖然ObjectId設計成輕量型的,易於產生的,但畢竟的產生的時候還是會產生開銷.在用戶端產生體現了
MongoDB的設計理念:能從服務端轉移到驅動程式來做的就盡量轉移.這種理念的原因是:擴充應用程式層比
擴充資料庫層容易的多,將事務交由用戶端處理,就減輕了資料庫擴充的負擔.
2.在用戶端產生ObjectId,驅動程式能夠提供更豐富的API.如驅動程式可以有自己的insert方法,可以返回產生
的ObjectId,也可以直接將其插入文檔.如果驅動程式允許伺服器產生ObjectId,那麼將需要單獨的查詢,以確定
插入的文檔中的"_id"值.