摘要:如將構(gòu)造函數(shù)作為函數(shù)進(jìn)行調(diào)用即不包括的方式,返回的是日期的字符串表示,而非日期對(duì)象。如果不注意這一點(diǎn),沒(méi)有始終使用日期構(gòu)造函數(shù),將得到一堆混亂的日期對(duì)象和日期的字符串。關(guān)于日期類的完整解釋,以及構(gòu)造函數(shù)的參數(shù)格式,參見規(guī)范節(jié)。
上一篇文章:MongoDB指南---2、MongoDB基礎(chǔ)知識(shí)-文檔、集合、數(shù)據(jù)庫(kù)、客戶端
下一篇文章:MongoDB指南---4、MongoDB基礎(chǔ)知識(shí)-使用MongoDB Shell
本章開始部分介紹了文檔的基本概念,現(xiàn)在你已經(jīng)會(huì)啟動(dòng)、運(yùn)行MongoDB,也會(huì)在shell中進(jìn)行一些操作了。這一節(jié)的內(nèi)容會(huì)更加深入。MongoDB支持將多種數(shù)據(jù)類型作為文檔中的值,下面將一一介紹。
2.6.1 基本數(shù)據(jù)類型在概念上,MongoDB的文檔與JavaScript中的對(duì)象相近,因而可認(rèn)為它類似于JSON。JSON(http://www.json.org)是一種簡(jiǎn)單的數(shù)據(jù)表示方式:其規(guī)范僅用一段文字就能描述清楚(其官網(wǎng)證明了這點(diǎn)),且僅包含6種數(shù)據(jù)類型。這樣有很多好處:易于理解、易于解析、易于記憶。然而,從另一方面來(lái)說(shuō),因?yàn)橹挥衝ull、布爾、數(shù)字、字符串、數(shù)組和對(duì)象這幾種數(shù)據(jù)類型,所以JSON的表達(dá)能力有一定的局限。
雖然JSON具備的這些類型已具有很強(qiáng)的表現(xiàn)力,但絕大多數(shù)應(yīng)用(尤其是在與數(shù)據(jù)庫(kù)打交道時(shí))都還需要其他一些重要的類型。例如,JSON沒(méi)有日期類型,這使原本容易的日期處理變得煩人。另外,JSON只有一種數(shù)字類型,無(wú)法區(qū)分浮點(diǎn)數(shù)和整數(shù),更別說(shuō)區(qū)分32位和64位數(shù)字了。再者,JSON無(wú)法表示其他一些通用類型,如正則表達(dá)式或函數(shù)。
MongoDB在保留JSON基本鍵/值對(duì)特性的基礎(chǔ)上,添加了其他一些數(shù)據(jù)類型。 在不同的編程語(yǔ)言下,這些類型的確切表示有些許差異。下面說(shuō)明MongoDB支持的其他通用類型,以及如何在文檔中使用它們。
null用于表示空值或者不存在的字段:
{"x" : null}布爾型
布爾類型有兩個(gè)值true和false:
{"x" : true}數(shù)值
shell默認(rèn)使用64位浮點(diǎn)型數(shù)值。因此,以下數(shù)值在shell中是很“正常”的:
{"x" : 3.14}
或:
{"x" : 3}
對(duì)于整型值,可使用NumberInt類(表示4字節(jié)帶符號(hào)整數(shù))或NumberLong類(表示8字符帶符號(hào)整數(shù)),分別舉例如下:
{"x" : NumberInt("3")} {"x" : NumberLong("3")}字符串
UTF-8字符串都可表示為字符串類型的數(shù)據(jù):
{"x" : "foobar"}日期
日期被存儲(chǔ)為自新紀(jì)元以來(lái)經(jīng)過(guò)的毫秒數(shù),不存儲(chǔ)時(shí)區(qū):
{"x" : new Date()}正則表達(dá)式
查詢時(shí),使用正則表達(dá)式作為限定條件,語(yǔ)法也與JavaScript的正則表達(dá)式語(yǔ)法相同:
{"x" : /foobar/i}數(shù)組
數(shù)據(jù)列表或數(shù)據(jù)集可以表示為數(shù)組:
{"x" : ["a", "b", "c"]}內(nèi)嵌文檔
文檔可嵌套其他文檔,被嵌套的文檔作為父文檔的值:
{"x" : {"foo" : "bar"}}對(duì)象id
對(duì)象id是一個(gè)12字節(jié)的ID,是文檔的唯一標(biāo)識(shí)。詳見2.6.5節(jié)。
{"x" : ObjectId()}
還有一些不那么常用,但可能有需要的類型,包括下面這些。
二進(jìn)制數(shù)據(jù)二進(jìn)制數(shù)據(jù)是一個(gè)任意字節(jié)的字符串。它不能直接在shell中使用。如果要將非UTF-8字符保存到數(shù)據(jù)庫(kù)中,二進(jìn)制數(shù)據(jù)是唯一的方式。
代碼查詢和文檔中可以包括任意JavaScript代碼:
{"x" : function() { /* ... */ }}
另外,有幾種大多數(shù)情況下僅在內(nèi)部使用(或被其他類型取代)的類型。在本書中,出現(xiàn)這種情況時(shí)會(huì)特別說(shuō)明。
關(guān)于MongoDB數(shù)據(jù)格式的更多信息,參考附錄B。
在JavaScript中,Date類可以用作MongoDB的日期類型。創(chuàng)建日期對(duì)象時(shí),應(yīng)使用new Date(…),而非Date(…)。如將構(gòu)造函數(shù)(constructor)作為函數(shù)進(jìn)行調(diào)用(即不包括new的方式),返回的是日期的字符串表示,而非日期(Date)對(duì)象。這個(gè)結(jié)果與MongoDB無(wú)關(guān),是JavaScript的工作機(jī)制決定的。如果不注意這一點(diǎn),沒(méi)有始終使用日期(Date)構(gòu)造函數(shù),將得到一堆混亂的日期對(duì)象和日期的字符串。由于日期和字符串之間無(wú)法匹配,所以執(zhí)行刪除、更新及查詢等幾乎所有操作時(shí)會(huì)導(dǎo)致很多問(wèn)題。
關(guān)于JavaScript日期類的完整解釋,以及構(gòu)造函數(shù)的參數(shù)格式,參見ECMAScript規(guī)范15.9節(jié)(http://www.ecmascript.org)。
shell根據(jù)本地時(shí)區(qū)設(shè)置顯示日期對(duì)象。然而,數(shù)據(jù)庫(kù)中存儲(chǔ)的日期僅為新紀(jì)元以來(lái)的毫秒數(shù),并未存儲(chǔ)對(duì)應(yīng)的時(shí)區(qū)。(當(dāng)然,可將時(shí)區(qū)信息存儲(chǔ)為另一個(gè)鍵的值)。
數(shù)組是一組值,它既能作為有序?qū)ο螅ㄈ缌斜怼;蜿?duì)列),也能作為無(wú)序?qū)ο螅ㄈ鐢?shù)據(jù)集)來(lái)操作。
在下面的文檔中,"things"這個(gè)鍵的值是一個(gè)數(shù)組:
{"things" : ["pie", 3.14]}
此例表示,數(shù)組可包含不同數(shù)據(jù)類型的元素(在此,是一個(gè)字符串和一個(gè)浮點(diǎn)數(shù))。實(shí)際上,常規(guī)的鍵/值對(duì)支持的所有值都可以作為數(shù)組的值,數(shù)組中甚至可以套嵌數(shù)組。
文檔中的數(shù)組有個(gè)奇妙的特性,就是MongoDB能“理解”其結(jié)構(gòu),并知道如何“深入”數(shù)組內(nèi)部對(duì)其內(nèi)容進(jìn)行操作。這樣就能使用數(shù)組內(nèi)容對(duì)數(shù)組進(jìn)行查詢和構(gòu)建索引了。例如,之前的例子中,MongoDB可以查詢出"things"數(shù)組中包含3.14這個(gè)元素的所有文檔。要是經(jīng)常使用這個(gè)查詢,可以對(duì)"things"創(chuàng)建索引來(lái)提高性能。
MongoDB可以使用原子更新對(duì)數(shù)組內(nèi)容進(jìn)行修改,比如深入數(shù)組內(nèi)部將pie改為pi。本書后面還會(huì)介紹更多這種操作的例子。
文檔可以作為鍵的值,這樣的文檔就是內(nèi)嵌文檔。使用內(nèi)嵌文檔,可以使數(shù)據(jù)組織方式更加自然,不用非得存成扁平結(jié)構(gòu)的鍵/值對(duì)。
例如,用一個(gè)文檔來(lái)表示一個(gè)人,同時(shí)還要保存他的地址,可以將地址信息保存在內(nèi)嵌的"address"文檔中:
{ "name" : "John Doe", "address" : { "street" : "123 Park Street", "city" : "Anytown", "state" : "NY" } }
上面例子中"address"鍵的值是一個(gè)內(nèi)嵌文檔,這個(gè)文檔有自己的"street"、"city"和"state"鍵以及對(duì)應(yīng)的值。
同數(shù)組一樣,MongoDB能夠“理解”內(nèi)嵌文檔的結(jié)構(gòu),并能“深入”其中構(gòu)建索引、執(zhí)行查詢或者更新。
稍后會(huì)深入討論模式設(shè)計(jì),但是從這個(gè)簡(jiǎn)單的例子也可以看得出內(nèi)嵌文檔可以改變處理數(shù)據(jù)的方式。在關(guān)系型數(shù)據(jù)庫(kù)中,這個(gè)例子中的文檔一般會(huì)被拆分成兩個(gè)表中的兩個(gè)行 (“people”和“address”各一行)。在MongoDB中,就可以直接將地址文檔嵌入到人員文檔中。使用得當(dāng)?shù)脑挘瑑?nèi)嵌文檔會(huì)使信息的表示方式更加自然(通常也會(huì)更高效)。
MongoDB這樣做的壞處就是會(huì)導(dǎo)致更多的數(shù)據(jù)重復(fù)。假設(shè)“address”是關(guān)系數(shù)據(jù)庫(kù)中的一個(gè)獨(dú)立的表,我們需要修正地址中的拼寫錯(cuò)誤。當(dāng)我們對(duì)“people”和“address”執(zhí)行連接操作時(shí),使用這個(gè)地址的每個(gè)人的信息都會(huì)得到更新。但是在MongoDB中,則需要對(duì)每個(gè)人的文檔分別修正拼寫錯(cuò)誤。
MongoDB中存儲(chǔ)的文檔必須有一個(gè)"_id"鍵。這個(gè)鍵的值可以是任何類型的,默認(rèn)是個(gè)ObjectId對(duì)象。在一個(gè)集合里面,每個(gè)文檔都有唯一的"_id",確保集合里面每個(gè)文檔都能被唯一標(biāo)識(shí)。如果有兩個(gè)集合的話,兩個(gè)集合可以都有一個(gè)"_id"的值為123,但是每個(gè)集合里面只能有一個(gè)文檔的"_id"值為123。
1. ObjectIdObjectId是"_id"的默認(rèn)類型。它設(shè)計(jì)成輕量型的,不同的機(jī)器都能用全局唯一的同種方法方便地生成它。這是 MongoDB采用ObjectId,而不是其他比較常規(guī)的做法(比如自動(dòng)增加的主鍵)的主要原因,因?yàn)樵诙鄠€(gè)服務(wù)器上同步自動(dòng)增加主鍵值既費(fèi)力又費(fèi)時(shí)。因?yàn)樵O(shè)計(jì)MongoDB的初衷就是用作分布式數(shù)據(jù)庫(kù),所以能夠在分片環(huán)境中生成唯一的標(biāo)示符非常重要。
ObjectId使用12字節(jié)的存儲(chǔ)空間,是一個(gè)由24個(gè)十六進(jìn)制數(shù)字組成的字符串(每個(gè)字節(jié)可以存儲(chǔ)兩個(gè)十六進(jìn)制數(shù)字)。由于看起來(lái)很長(zhǎng),不少人會(huì)覺得難以處理。但關(guān)鍵是要知道這個(gè)長(zhǎng)長(zhǎng)的ObjectId是實(shí)際存儲(chǔ)數(shù)據(jù)的兩倍長(zhǎng)。
如果快速連續(xù)創(chuàng)建多個(gè)ObjectId,會(huì)發(fā)現(xiàn)每次只有最后幾位數(shù)字有變化。另外,中間的幾位數(shù)字也會(huì)變化(要是在創(chuàng)建的過(guò)程中停頓幾秒鐘)。這是ObjectId的創(chuàng)建方式導(dǎo)致的。ObjectId的12字節(jié)按照如下方式生成:
前面講到,如果插入文檔時(shí)沒(méi)有"_id"鍵,系統(tǒng)會(huì)自動(dòng)幫你創(chuàng)建一個(gè)。可以由MongoDB服務(wù)器來(lái)做這件事,但通常會(huì)在客戶端由驅(qū)動(dòng)程序完成。這一做法非常好地體現(xiàn)了MongoDB的哲學(xué):能交給客戶端驅(qū)動(dòng)程序來(lái)做的事情就不要交給服務(wù)器來(lái)做。這種理念背后的原因是,即便是像MongoDB這樣擴(kuò)展性非常好的數(shù)據(jù)庫(kù),擴(kuò)展應(yīng)用層也要比擴(kuò)展數(shù)據(jù)庫(kù)層容易得多。將工作交由客戶端來(lái)處理,就減輕了數(shù)據(jù)庫(kù)擴(kuò)展的負(fù)擔(dān)。
上一篇文章:MongoDB指南---2、MongoDB基礎(chǔ)知識(shí)-文檔、集合、數(shù)據(jù)庫(kù)、客戶端
下一篇文章:MongoDB指南---4、MongoDB基礎(chǔ)知識(shí)-使用MongoDB Shell
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/43991.html
摘要:如將構(gòu)造函數(shù)作為函數(shù)進(jìn)行調(diào)用即不包括的方式,返回的是日期的字符串表示,而非日期對(duì)象。如果不注意這一點(diǎn),沒(méi)有始終使用日期構(gòu)造函數(shù),將得到一堆混亂的日期對(duì)象和日期的字符串。關(guān)于日期類的完整解釋,以及構(gòu)造函數(shù)的參數(shù)格式,參見規(guī)范節(jié)。 上一篇文章:MongoDB指南---2、MongoDB基礎(chǔ)知識(shí)-文檔、集合、數(shù)據(jù)庫(kù)、客戶端下一篇文章:MongoDB指南---4、MongoDB基礎(chǔ)知識(shí)-使用M...
摘要:上一篇文章指南簡(jiǎn)介下一篇文章指南基礎(chǔ)知識(shí)數(shù)據(jù)類型非常強(qiáng)大但很容易上手。把同種類型的文檔放在一個(gè)集合里,數(shù)據(jù)會(huì)更加集中。命名集合使用名稱進(jìn)行標(biāo)識(shí)。集合名不能是空字符串。簡(jiǎn)單起見,數(shù)據(jù)庫(kù)名應(yīng)全部小寫。 上一篇文章:MongoDB指南---1、MongoDB簡(jiǎn)介下一篇文章:MongoDB指南---3、MongoDB基礎(chǔ)知識(shí)-數(shù)據(jù)類型 MongoDB非常強(qiáng)大但很容易上手。本章會(huì)介紹一些Mon...
摘要:上一篇文章指南簡(jiǎn)介下一篇文章指南基礎(chǔ)知識(shí)數(shù)據(jù)類型非常強(qiáng)大但很容易上手。把同種類型的文檔放在一個(gè)集合里,數(shù)據(jù)會(huì)更加集中。命名集合使用名稱進(jìn)行標(biāo)識(shí)。集合名不能是空字符串。簡(jiǎn)單起見,數(shù)據(jù)庫(kù)名應(yīng)全部小寫。 上一篇文章:MongoDB指南---1、MongoDB簡(jiǎn)介下一篇文章:MongoDB指南---3、MongoDB基礎(chǔ)知識(shí)-數(shù)據(jù)類型 MongoDB非常強(qiáng)大但很容易上手。本章會(huì)介紹一些Mon...
摘要:例如,假設(shè)要?jiǎng)h除集合中所有為的人刪除數(shù)據(jù)是永久性的,不能撤銷,也不能恢復(fù)。刪除速度刪除文檔通常很快,但是如果要清空整個(gè)集合,那么使用直接刪除集合會(huì)更快然后在這個(gè)空集合上重建各項(xiàng)索引。上一篇文章指南基礎(chǔ)知識(shí)使用下一篇文章指南更新文檔 上一篇文章:MongoDB指南---4、MongoDB基礎(chǔ)知識(shí)-使用MongoDB Shell下一篇文章:MongoDB指南---6、更新文檔 本章會(huì)介紹...
摘要:例如,假設(shè)要?jiǎng)h除集合中所有為的人刪除數(shù)據(jù)是永久性的,不能撤銷,也不能恢復(fù)。刪除速度刪除文檔通常很快,但是如果要清空整個(gè)集合,那么使用直接刪除集合會(huì)更快然后在這個(gè)空集合上重建各項(xiàng)索引。上一篇文章指南基礎(chǔ)知識(shí)使用下一篇文章指南更新文檔 上一篇文章:MongoDB指南---4、MongoDB基礎(chǔ)知識(shí)-使用MongoDB Shell下一篇文章:MongoDB指南---6、更新文檔 本章會(huì)介紹...
閱讀 3903·2021-11-22 13:54
閱讀 2675·2021-09-30 09:48
閱讀 2361·2021-09-28 09:36
閱讀 3113·2021-09-22 15:26
閱讀 1343·2019-08-30 15:55
閱讀 2509·2019-08-30 15:54
閱讀 1426·2019-08-30 14:17
閱讀 2341·2019-08-28 18:25