關(guān)系型數(shù)據(jù)庫(kù)與非關(guān)系型數(shù)據(jù)庫(kù):
MongoDB特性
MongoDB與RDBMS存儲(chǔ)結(jié)構(gòu)
MongoDB與RDBMS最大的區(qū)別在于: 沒(méi)有固定的行列組織數(shù)據(jù)結(jié)構(gòu)
一、MongoDB簡(jiǎn)介
MongoDB是一款強(qiáng)大、靈活、且易于擴(kuò)展的通用型數(shù)據(jù)庫(kù)。
1、易用性
MongoDB是一個(gè)面向文檔(document-oriented)的數(shù)據(jù)庫(kù),而不是關(guān)系型數(shù)據(jù)庫(kù)。 不采用關(guān)系型主要是為了獲得更好得擴(kuò)展性。當(dāng)然還有一些其他好處,與關(guān)系數(shù)據(jù)庫(kù)相比,面向文檔的數(shù)據(jù)庫(kù)不再有“行“(row)的概念取而代之的是更為靈活的“文檔”(document)模型。 通過(guò)在文檔中嵌入文檔和數(shù)組,面向文檔的方法能夠僅使用一條記錄來(lái)表現(xiàn)復(fù)雜的層級(jí)關(guān)系,這與現(xiàn)代的面向?qū)ο笳Z(yǔ)言的開(kāi)發(fā)者對(duì)數(shù)據(jù)的看法一致。另外,不再有預(yù)定義模式(predefined schema): 文檔的鍵(key)和值(value)不再是固定的類(lèi)型和大小。由于沒(méi)有固定的模式,根據(jù)需要添加或刪除字段變得更容易了。通常由于開(kāi)發(fā)者能夠進(jìn)行快速迭代,所以開(kāi)發(fā)進(jìn)程得以加快。而且,實(shí)驗(yàn)更容易進(jìn)行。開(kāi)發(fā)者能?chē)L試大量的數(shù)據(jù)模型,從中選一個(gè)最好的。
2、易擴(kuò)展性
應(yīng)用程序數(shù)據(jù)集的大小正在以不可思議的速度增長(zhǎng)。隨著可用帶寬的增長(zhǎng)和存儲(chǔ)器價(jià)格的下降,即使是一個(gè)小規(guī)模的應(yīng)用程序,需要存儲(chǔ)的數(shù)據(jù)量也可能大的驚人,甚至超出了很多數(shù)據(jù)庫(kù)的處理能力。過(guò)去非常罕見(jiàn)的T級(jí)數(shù)據(jù),現(xiàn)在已經(jīng)是司空見(jiàn)慣了。 由于需要存儲(chǔ)的數(shù)據(jù)量不斷增長(zhǎng),開(kāi)發(fā)者面臨一個(gè)問(wèn)題:應(yīng)該如何擴(kuò)展數(shù)據(jù)庫(kù),分為縱向擴(kuò)展和橫向擴(kuò)展,縱向擴(kuò)展是最省力的做法,但缺點(diǎn)是大型機(jī)一般都非常貴,而且當(dāng)數(shù)據(jù)量達(dá)到機(jī)器的物理極限時(shí),花再多的錢(qián)也買(mǎi)不到更強(qiáng)的機(jī)器了,此時(shí)選擇橫向擴(kuò)展更為合適,但橫向擴(kuò)展帶來(lái)的另外一個(gè)問(wèn)題就是需要管理的機(jī)器太多。 MongoDB的設(shè)計(jì)采用橫向擴(kuò)展。面向文檔的數(shù)據(jù)模型使它能很容易地在多臺(tái)服務(wù)器之間進(jìn)行數(shù)據(jù)分割。MongoDB能夠自動(dòng)處理跨集群的數(shù)據(jù)和負(fù)載,自動(dòng)重新分配文檔,以及將用戶的請(qǐng)求路由到正確的機(jī)器上。這樣,開(kāi)發(fā)者能夠集中精力編寫(xiě)應(yīng)用程序,而不需要考慮如何擴(kuò)展的問(wèn)題。如果一個(gè)集群需要更大的容量,只需要向集群添加新服務(wù)器,MongoDB就會(huì)自動(dòng)將現(xiàn)有的數(shù)據(jù)向新服務(wù)器傳送。
3、豐富的功能
MongoDB作為一款通用型數(shù)據(jù)庫(kù),除了能夠創(chuàng)建、讀取、更新和刪除數(shù)據(jù)之外,還提供了一系列不斷擴(kuò)展的獨(dú)特功能。 #1、索引 支持通用二級(jí)索引,允許多種快速查詢,且提供唯一索引、復(fù)合索引、地理空間索引、全文索引。 #2、聚合 支持聚合管道,用戶能通過(guò)簡(jiǎn)單的片段創(chuàng)建復(fù)雜的集合,并通過(guò)數(shù)據(jù)庫(kù)自動(dòng)優(yōu)化。 #3、特殊的集合類(lèi)型 支持存在時(shí)間有限的集合,適用于那些將在某個(gè)時(shí)刻過(guò)期的數(shù)據(jù),如會(huì)話session。類(lèi)似地,MongoDB也支持固定大小的集合,用于保存近期數(shù)據(jù),如日志等… #4、文件存儲(chǔ) 支持一種非常易用的協(xié)議,用于存儲(chǔ)大文件和文件元數(shù)據(jù)。MongoDB并不具備一些在關(guān)系型數(shù)據(jù)庫(kù)中很普遍的功能,如鏈接join和復(fù)雜的多行事務(wù)。省略這些的功能是處于架構(gòu)上的考慮,或者說(shuō)為了得到更好的擴(kuò)展性,因?yàn)樵诜植际较到y(tǒng)中這兩個(gè)功能難以高效地實(shí)現(xiàn)。
4、卓越的性能
MongoDB的一個(gè)主要目標(biāo)是提供卓越的性能,這很大程度上決定了MongoDB的設(shè)計(jì)。MongoDB把盡可能多的內(nèi)存用作緩存cache,視圖為每次查詢自動(dòng)選擇正確的索引。 總之各方面的設(shè)計(jì)都旨在保持它的高性能。雖然MongoDB非常強(qiáng)大并試圖保留關(guān)系型數(shù)據(jù)庫(kù)的很多特性,但它并不追求具備關(guān)系型數(shù)據(jù)庫(kù)的所有功能。只要有可能,數(shù)據(jù)庫(kù)服務(wù)器就會(huì)將處理邏輯交給客戶端。這種精簡(jiǎn)方式的設(shè)計(jì)是MongoDB能夠?qū)崿F(xiàn)如此高性能的原因之一。
二、MongoDB基礎(chǔ)知識(shí)
1、文檔是MongoDB的核心概念。文檔就是鍵值對(duì)的一個(gè)有序集{‘msg’:’hello’,’foo’:3}。類(lèi)似于python中的有序字典。
需要注意的是:#1、文檔中的鍵/值對(duì)是有序的。#2、文檔中的值不僅可以是在雙引號(hào)里面的字符串,還可以是其他幾種數(shù)據(jù)類(lèi)型(甚至可以是整個(gè)嵌入的文檔)。#3、MongoDB區(qū)分類(lèi)型和大小寫(xiě)。#4、MongoDB的文檔不能有重復(fù)的鍵。#5、文檔中的值可以是多種不同的數(shù)據(jù)類(lèi)型,也可以是一個(gè)完整的內(nèi)嵌文檔。文檔的鍵是字符串。除了少數(shù)例外情況,鍵可以使用任意UTF-8字符。文檔鍵命名規(guī)范:#1、鍵不能含有 (空字符)。這個(gè)字符用來(lái)表示鍵的結(jié)尾。#2、.和$有特別的意義,只有在特定環(huán)境下才能使用。#3、以下劃線”_”開(kāi)頭的鍵是保留的(不是嚴(yán)格要求的)。
2、集合就是一組文檔。如果將MongoDB中的一個(gè)文檔比喻為關(guān)系型數(shù)據(jù)的一行,那么一個(gè)集合就是相當(dāng)于一張表
#1、集合存在于數(shù)據(jù)庫(kù)中,通常情況下為了方便管理,不同格式和類(lèi)型的數(shù)據(jù)應(yīng)該插入到不同的集合,但其實(shí)集合沒(méi)有固定的結(jié)構(gòu),這意味著我們完全可以把不同格式和類(lèi)型的數(shù)據(jù)統(tǒng)統(tǒng)插入一個(gè)集合中。#2、組織子集合的方式就是使用“.”,分隔不同命名空間的子集合。比如一個(gè)具有博客功能的應(yīng)用可能包含兩個(gè)集合,分別是blog.posts和blog.authors,這是為了使組織結(jié)構(gòu)更清晰,這里的blog集合(這個(gè)集合甚至不需要存在)跟它的兩個(gè)子集合沒(méi)有任何關(guān)系。在MongoDB中,使用子集合來(lái)組織數(shù)據(jù)非常高效,值得推薦#3、當(dāng)?shù)谝粋€(gè)文檔插入時(shí),集合就會(huì)被創(chuàng)建。合法的集合名:集合名不能是空字符串””。集合名不能含有字符(空字符),這個(gè)字符表示集合名的結(jié)尾。集合名不能以”system.”開(kāi)頭,這是為系統(tǒng)集合保留的前綴。用戶創(chuàng)建的集合名字不能含有保留字符。有些驅(qū)動(dòng)程序的確支持在集合名里面包含,這是因?yàn)槟承┫到y(tǒng)生成的集合中包含該字符。除非你要訪問(wèn)這種系統(tǒng)創(chuàng)建的集合,否則千萬(wàn)不要在名字里出現(xiàn)$。
3、數(shù)據(jù)庫(kù):在MongoDB中,多個(gè)文檔組成集合,多個(gè)集合可以組成數(shù)據(jù)庫(kù)
數(shù)據(jù)庫(kù)也通過(guò)名字來(lái)標(biāo)識(shí)。數(shù)據(jù)庫(kù)名可以是滿足以下條件的任意UTF-8字符串:#1、不能是空字符串(””)。#2、不得含有’ ‘(空格)、.、$、/、和 (空字符)。#3、應(yīng)全部小寫(xiě)。#4、最多64字節(jié)。有一些數(shù)據(jù)庫(kù)名是保留的,可以直接訪問(wèn)這些有特殊作用的數(shù)據(jù)庫(kù)。#1、admin: 從身份認(rèn)證的角度講,這是“root”數(shù)據(jù)庫(kù),如果將一個(gè)用戶添加到admin數(shù)據(jù)庫(kù),這個(gè)用戶將自動(dòng)獲得所有數(shù)據(jù)庫(kù)的權(quán)限。再者,一些特定的服務(wù)器端命令也只能從admin數(shù)據(jù)庫(kù)運(yùn)行,如列出所有數(shù)據(jù)庫(kù)或關(guān)閉服務(wù)器#2、local: 這個(gè)數(shù)據(jù)庫(kù)永遠(yuǎn)都不可以復(fù)制,且一臺(tái)服務(wù)器上的所有本地集合都可以存儲(chǔ)在這個(gè)數(shù)據(jù)庫(kù)中#3、config: MongoDB用于分片設(shè)置時(shí),分片信息會(huì)存儲(chǔ)在config數(shù)據(jù)庫(kù)中
4、強(qiáng)調(diào):把數(shù)據(jù)庫(kù)名添加到集合名前,得到集合的完全限定名,即命名空間
例如:如果要使用cms數(shù)據(jù)庫(kù)中的blog.posts集合,這個(gè)集合的命名空間就是cmd.blog.posts。命名空間的長(zhǎng)度不得超過(guò)121個(gè)字節(jié),且在實(shí)際使用中應(yīng)該小于100個(gè)字節(jié)
三、安裝
1、安裝
#1、安裝路徑為D:MongoDB,將D:MongoDBbin目錄加入環(huán)境變量#2、新建目錄與文件D:MongoDBdatadbD:MongoDBlogmongod.log#3、新建配置文件mongod.cfg,參考:https://docs.mongodb.com/manual/reference/configuration-options/systemLog: destination: file path: “D:MongoDBlogmongod.log” logAppend: truestorage: journal: enabled: true dbPath: “D:MongoDBdatadb”net: bindIp: 0.0.0.0 port: 27017setParameter: enableLocalhostAuthBypass: false #4、制作系統(tǒng)服務(wù)mongod –config “D:MongoDBmongod.cfg” –bind_ip 0.0.0.0 –install或者直接在命令行指定配置mongod –bind_ip 0.0.0.0 –port 27017 –logpath D:MongoDBlogmongod.log –logappend –dbpath D:MongoDBdatadb –serviceName “MongoDB” –serviceDisplayName “MongoDB” –install#5、啟動(dòng)關(guān)閉net start MongoDBnet stop MongoDB#6、登錄mongo鏈接:http://www.runoob.com/mongodb/mongodb-window-install.html
2、賬號(hào)管理
#賬號(hào)管理:https://docs.mongodb.com/master/tutorial/enable-authentication/# 1、創(chuàng)建賬號(hào)use admindb.createUser( { user: “root”, pwd: “123”, roles: [ { role: “root”, db: “admin” } ] })use testdb.createUser( { user: “tank”, pwd: “123”, roles: [ { role: “readWrite”, db: “test” }, { role: “read”, db: “db1” } ] })# 2、重啟數(shù)據(jù)庫(kù)mongod –removemongod –config “C:mongodbmongod.cfg” –bind_ip 0.0.0.0 –install –auth# 3、登錄:注意使用雙引號(hào)而非單引號(hào)mongo –port 27017 -u “root” -p “123” –authenticationDatabase “admin”也可以在登錄之后用db.auth(“賬號(hào)”,”密碼”)登錄mongouse admindb.auth(“root”,”123″)# 推薦博客:https://www.cnblogs.com/zhoujinyi/p/4610050.htmlmongo -u “root” -p “123” –authenticationDatabase “admin”
mysql -u root -p 123
3、命令行shell
1、mongo 127.0.0.1:27017/config #連接到任何數(shù)據(jù)庫(kù)config2、mongo –nodb #不連接到任何數(shù)據(jù)庫(kù)3、啟動(dòng)之后,在需要時(shí)運(yùn)行new Mongo(hostname)命令就可以連接到想要的mongod了:> conn=new Mongo(‘127.0.0.1:27017’)connection to 127.0.0.1:27017> db=conn.getDB(‘admin’)admin4、help查看幫助5、mongo時(shí)一個(gè)簡(jiǎn)化的JavaScript shell,是可以執(zhí)行JavaScript腳本的shell命令行
四、基本數(shù)據(jù)類(lèi)型
1、在概念上,MongoDB的文檔與Javascript的對(duì)象相近,因而可以認(rèn)為它類(lèi)似于JSON。JSON(http://www.json.org)是一種簡(jiǎn)單的數(shù)據(jù)表示方式:其規(guī)范僅用一段文字就能描述清楚(其官網(wǎng)證明了這點(diǎn)),且僅包含六種數(shù)據(jù)類(lèi)型。
2、這樣有很多好處:易于理解、易于解析、易于記憶。然而從另一方面說(shuō),因?yàn)橹挥衝ull、布爾、數(shù)字、字符串、數(shù)字和對(duì)象這幾種數(shù)據(jù)類(lèi)型,所以JSON的表達(dá)能力有一定的局限。
3、雖然JSON具備的這些類(lèi)型已經(jīng)具有很強(qiáng)的表現(xiàn)力,但絕大數(shù)應(yīng)用(尤其是在于數(shù)據(jù)庫(kù)打交道時(shí))都還需要其他一些重要的類(lèi)型。例如,JSON沒(méi)有日期類(lèi)型,這使得原本容易日期處理變得煩人。另外,JSON只有一種數(shù)字類(lèi)型,無(wú)法區(qū)分浮點(diǎn)數(shù)和整數(shù),更別區(qū)分32位和64位了。再者JSON無(wú)法表示其他一些通用類(lèi)型,如正則表達(dá)式或函數(shù)。
4、MongoDB在保留了JSON基本鍵/值對(duì)特性的基礎(chǔ)上,添加了其他一些數(shù)據(jù)類(lèi)型。在不同的編程語(yǔ)言下,這些類(lèi)型的確切表示有些許差異。下面說(shuō)明了MongoDB支持的其他通用類(lèi)型,以及如何正在文檔中使用它們
#1、null:用于表示空或不存在的字段d={‘x’:null}#2、布爾型:true和falsed={‘x’:true,’y’:false}#3、數(shù)值d={‘x’:3,’y’:3.1415926}#4、字符串d={‘x’:’kermit’}#5、日期d={‘x’:new Date()}d.x.getHours()#6、正則表達(dá)式d={‘pattern’:/^kermit.*?nb$/i}正則寫(xiě)在//內(nèi),后面的i代表:i 忽略大小寫(xiě)m 多行匹配模式x 忽略非轉(zhuǎn)義的空白字符s 單行匹配模式#7、數(shù)組d={‘x’:[1,’a’,’v’]}#8、內(nèi)嵌文檔user={‘name’:’tank’,’addr’:{‘country’:’China’,’city’:’YT’}}user.addr.country#9、對(duì)象id:是一個(gè)12字節(jié)的ID,是文檔的唯一標(biāo)識(shí),不可變d={‘x’:ObjectId()}
5、_id 和 ObjectId
MongoDB中存儲(chǔ)的文檔必須有一個(gè)”_id”鍵。這個(gè)鍵的值可以是任意類(lèi)型,默認(rèn)是個(gè)ObjectId對(duì)象。在一個(gè)集合里,每個(gè)文檔都有唯一的“_id”,確保集合里每個(gè)文檔都能被唯一標(biāo)識(shí)。不同集合”_id”的值可以重復(fù),但同一集合內(nèi)”_id”的值必須唯一#1、ObjectIdObjectId是”_id”的默認(rèn)類(lèi)型。因?yàn)樵O(shè)計(jì)MongoDb的初衷就是用作分布式數(shù)據(jù)庫(kù),所以能夠在分片環(huán)境中生成唯一的標(biāo)識(shí)符非常重要,而常規(guī)的做法:在多個(gè)服務(wù)器上同步自動(dòng)增加主鍵既費(fèi)時(shí)又費(fèi)力,這就是MongoDB采用ObjectId的原因。ObjectId采用12字節(jié)的存儲(chǔ)空間,是一個(gè)由24個(gè)十六進(jìn)制數(shù)字組成的字符串 0|1|2|3| 4|5|6| 7|8 9|10|11 時(shí)間戳 機(jī)器 PID 計(jì)數(shù)器如果快速創(chuàng)建多個(gè)ObjectId,會(huì)發(fā)現(xiàn)每次只有最后幾位有變化。另外,中間的幾位數(shù)字也會(huì)變化(要是在創(chuàng)建過(guò)程中停頓幾秒)。這是ObjectId的創(chuàng)建方式導(dǎo)致的,如上圖時(shí)間戳單位為秒,與隨后5個(gè)字節(jié)組合起來(lái),提供了秒級(jí)的唯一性。這個(gè)4個(gè)字節(jié)隱藏了文檔的創(chuàng)建時(shí)間,絕大多數(shù)驅(qū)動(dòng)程序都會(huì)提供一個(gè)方法,用于從ObjectId中獲取這些信息。因?yàn)槭褂玫氖钱?dāng)前時(shí)間,很多用戶擔(dān)心要對(duì)服務(wù)器進(jìn)行時(shí)鐘同步。其實(shí)沒(méi)必要,因?yàn)闀r(shí)間戳的實(shí)際值并不重要,只要它總是不停增加就好。接下來(lái)3個(gè)字節(jié)是所在主機(jī)的唯一標(biāo)識(shí)符。通常是機(jī)器主機(jī)名的散列值。這樣就可以保證不同主機(jī)生成不同的ObjectId,不產(chǎn)生沖突接下來(lái)連個(gè)字節(jié)確保了在同一臺(tái)機(jī)器上并發(fā)的多個(gè)進(jìn)程產(chǎn)生的ObjectId是唯一的前9個(gè)字節(jié)確保了同一秒鐘不同機(jī)器不同進(jìn)程產(chǎn)生的ObjectId是唯一的。最后3個(gè)字節(jié)是一個(gè)自動(dòng)增加的 計(jì)數(shù)器。確保相同進(jìn)程的同一秒產(chǎn)生的ObjectId也是不一樣的。#2、自動(dòng)生成_id如果插入文檔時(shí)沒(méi)有”_id”鍵,系統(tǒng)會(huì)自幫你創(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ù)層容易的多。將工作交給客戶端做就減輕了數(shù)據(jù)庫(kù)擴(kuò)展的負(fù)擔(dān)。
五 CRUD操作 (create、read、update、delete)
1、數(shù)據(jù)庫(kù)操作
#1、增use config #如果數(shù)據(jù)庫(kù)不存在,則創(chuàng)建數(shù)據(jù)庫(kù),否則切換到指定數(shù)據(jù)庫(kù)。#2、查show dbs #查看所有可以看到,我們剛創(chuàng)建的數(shù)據(jù)庫(kù)config并不在數(shù)據(jù)庫(kù)的列表中, 要顯示它,我們需要向config數(shù)據(jù)庫(kù)插入一些數(shù)據(jù)。db.table1.insert({‘a’:1})#3、刪use config #先切換到要?jiǎng)h的庫(kù)下db.dropDatabase() #刪除當(dāng)前庫(kù)
2、集合操作
#1、增當(dāng)?shù)谝粋€(gè)文檔插入時(shí),集合就會(huì)被創(chuàng)建> use database1switched to db database1> db.table1.insert({‘a’:1})WriteResult({ “nInserted” : 1 })> db.table2.insert({‘b’:2})WriteResult({ “nInserted” : 1 })#2、查> show tablestable1table2#3、刪> db.table1.drop()true> show tablestable2
3、文檔操作
增
# 1、沒(méi)有指定_id則默認(rèn)ObjectId,_id不能重復(fù),且在插入后不可變#2、插入單條user0={ “name”:”tank”, “age”:10, ‘hobbies’:[‘music’,’read’,’dancing’], ‘addr’:{ ‘country’:’China’, ‘city’:’GD’ }}db.test.insert(user0)db.test.find()#3、插入多條user1={ “_id”:1, “name”:”tank”, “age”:10, ‘hobbies’:[‘music’,’read’,’dancing’], ‘addr’:{ ‘country’:’China’, ‘city’:’GuangZhou’ }}user2={ “_id”:2, “name”:”egon”, “age”:20, ‘hobbies’:[‘music’,’read’,’run’], ‘addr’:{ ‘country’:’China’, ‘city’:’ShanDong’ }}user3={ “_id”:3, “name”:”jason”, “age”:30, ‘hobbies’:[‘music’,’drink’], ‘addr’:{ ‘country’:’China’, ‘city’:’AnHui’ }}user4={ “_id”:4, “name”:”kevin”, “age”:40, ‘hobbies’:[‘music’,’read’,’dancing’,’tea’], ‘addr’:{ ‘country’:’China’, ‘city’:’ShanDong’ }}user5={ “_id”:5, “name”:”nick”, “age”:50, ‘hobbies’:[‘music’,’read’,], ‘addr’:{ ‘country’:’China’, ‘city’:’SH’ }}db.user.insertMany([user1,user2,user3,user4,user5])
查
# 比較運(yùn)算符# SQL:=,!=,>,=, 2;# 4.select * from db1.user where age = 2;# 6.select * from db1.user where id = 3 and id =3 and id 20;# 先獲取條件內(nèi)有的, 然后通過(guò)$and來(lái)進(jìn)行判斷select * from db1.user where id >=2 and id 30; # 2.$orselect * from db1.user where id >=0 and id = 4 or name = “egon”;# 3.$modselect * from db1.user where id % 2 =1;# 4.notdb.user.find({“_id”:{“$not”: {“$mod”:[2, 1]}}}) # 成員運(yùn)算 $in $nin 有egon與kevin名字的 沒(méi)有tank名字的 # 正則匹配 select * from db1.user where name regexp “^ke.*?(g|n)#34;; > db.user.find({“name”: /^ke.*?(g|n)$/i) # 查看指定字段 1代表True 0代表False select name, age from db1.user where name regexp “^ke.*?(n|g)#34;; db.user.find( { “name”: /^ke.*?(g|n)$/i }, { “_id”: 0, “name”: 1, “age”:1 } ) # 查詢數(shù)組相關(guān)的 # 查找音樂(lè)愛(ài)好的選手 db.user.find({ “hobbies”: “music” }) # 我要寫(xiě)多個(gè)愛(ài)好,有好多,寫(xiě)到哪里去 # 是不是寫(xiě)到數(shù)組里面去,查找既有音樂(lè)又有籃球的選手 db.user.find({ “hobbies”:{“$all”:[“music”, “basketball”]} }) # 查找第二個(gè)愛(ài)好是籃球的 db.user.find({“hobbies.1”: “basketball”})# 來(lái),你給我找出所有人的后兩個(gè)愛(ài)好 db.user.find( {}, { “_id”: 0, “name”: 0, “age”: 0, “addr”: 0, # “hobbies”: 1 “hobbies”: {“$slice”: -2} } ) # 查找第一和第二個(gè)愛(ài)好 db.user.find( {}, { “_id”: 0, “name”: 0, “age”: 0, “addr”: 0, “hobbies”: {“$slice”: [0, 2]} } ) # 補(bǔ)充: addr. # 針對(duì)查找內(nèi)嵌文檔的方式 # 我要找到addr下面city為hebei的 db.user.find({“addr.city”: “guangzhou”}) # 排序 # 升序 sort() db.user.find().sort({“_id”: 1}) # 降序 db.user.find().sort({“_id”: -1}) db.user.find().sort({“_id”: 1, “age”: -1}}) # 分頁(yè)查詢 limit() # 分頁(yè)兩條 db.user.find().limit(2) # 從第0頁(yè)開(kāi)始分頁(yè) db.user.find().limit(2).skip(0) # 從第2頁(yè)開(kāi)始分頁(yè) db.user.find().limit(2).skip(2) # 從第4頁(yè)開(kāi)始分頁(yè) db.user.find().limit(2).skip(4) # 查找數(shù)量 db.user.count() # 雜項(xiàng)目 db.t2.insert({“a”: 10, “b”:5}) db.t2.insert({“a”: 10, “b”:null}) db.t2.insert({“a”: 10}) # 查看key為b的和b的值為null的 db.t2.find({“b”:null}) { “_id”:ObjectId(“5c4888c5ce1c93e5aba5b2b3″),”a”:10,”b”:null} { “_id” : ObjectId(“5c4888c7ce1c93e5aba5b2b4”), “a” : 10 }