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.正則表達式
文檔中可以包含正則表達式,采用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"值.