網絡爬蟲之MongoDB數據庫的使用


一.簡潔

MongoDB是一款強大、靈活、且易於擴展的通用型數據庫

1、易用性

 

MongoDB是一個面向文檔(document-oriented)的數據庫,而不是關系型數據庫。 不采用關系型主要是為了獲得更好得擴展性。當然還有一些其他好處,與關系數據庫相比,面向文檔的數據庫不再有“行“(row)的概念取而代之的是更為靈活的“文檔”(document)模型。 通過在文檔中嵌入文檔和數組,面向文檔的方法能夠僅使用一條記錄來表現復雜的層級關系,這與現代的面向對象語言的開發者對數據的看法一致。 另外,不再有預定義模式(predefined schema):文檔的鍵(key)和值(value)不再是固定的類型和大小。由於沒有固定的模式,根據需要添加或刪除字段變得更容易了。
通常由於開發者能夠進行快速迭代,所以開發進程得以加快。而且,實驗更容易進行。開發者能嘗試大量的數據模型,
從中選一個最好的。

 

2、易擴展性

應用程序數據集的大小正在以不可思議的速度增長。隨着可用帶寬的增長和存儲器價格的下降,即使是一個小規模的應用程序,需要存儲的數據量也可能大的驚人,甚至超出
了很多數據庫的處理能力。過去非常罕見的T級數據,現在已經是司空見慣了。
由於需要存儲的數據量不斷增長,開發者面臨一個問題:應該如何擴展數據庫,分為縱向擴展和橫向擴展,縱向擴展是最省力的做法,但缺點是大型機一般都非常貴,而且
當數據量達到機器的物理極限時,花再多的錢也買不到更強的機器了,此時選擇橫向擴展更為合適,但橫向擴展帶來的另外一個問題就是需要管理的機器太多。
MongoDB的設計采用橫向擴展。面向文檔的數據模型使它能很容易地在多台服務器之間進行數據分割。MongoDB能夠自動處理跨集群的數據和負載,自動重新分配文檔,以及將
用戶的請求路由到正確的機器上。這樣,開發者能夠集中精力編寫應用程序,而不需要考慮如何擴展的問題。如果一個集群需要更大的容量,只需要向集群添加新服務器,
MongoDB就會自動將現有的數據向新服務器傳送

3、豐富的功能

MongoDB作為一款通用型數據庫,除了能夠創建、讀取、更新和刪除數據之外,還提供了一系列不斷擴展的獨特功能 #1、索引 支持通用二級索引,允許多種快速查詢,且提供唯一索引、復合索引、地理空間索引、全文索引 #2、聚合 支持聚合管道,用戶能通過簡單的片段創建復雜的集合,並通過數據庫自動優化 #3、特殊的集合類型 支持存在時間有限的集合,適用於那些將在某個時刻過期的數據,如會話session。類似地,MongoDB也支持固定大小的集合,用於保存近期數據,如日志 #4、文件存儲 支持一種非常易用的協議,用於存儲大文件和文件元數據。MongoDB並不具備一些在關系型數據庫中很普遍的功能,如鏈接join和復雜的多行事務。省略 這些的功能是處於架構上的考慮,或者說為了得到更好的擴展性,因為在分布式系統中這兩個功能難以高效地實現

4、卓越的性能

MongoDB的一個主要目標是提供卓越的性能,這很大程度上決定了MongoDB的設計。MongoDB把盡可能多的內存用作緩存cache,視圖為每次查詢自動選擇正確的索引。
總之各方面的設計都旨在保持它的高性能
雖然MongoDB非常強大並試圖保留關系型數據庫的很多特性,但它並不追求具備關系型數據庫的所有功能。只要有可能,數據庫服務器就會將處理邏輯交給客戶端。
這種精簡方式的設計是MongoDB能夠實現如此高性能的原因之一

 

二. MongoDB基礎知識

1、文檔是MongoDB的核心概念。文檔就是鍵值對的一個有序集{'msg':'hello','foo':3}。類似於python中的有序字典。

需要注意的是: #1、文檔中的鍵/值對是有序的。 #2、文檔中的值不僅可以是在雙引號里面的字符串,還可以是其他幾種數據類型(甚至可以是整個嵌入的文檔)。 #3、MongoDB區分類型和大小寫。 #4、MongoDB的文檔不能有重復的鍵。 #5、文檔中的值可以是多種不同的數據類型,也可以是一個完整的內嵌文檔。文檔的鍵是字符串。除了少數例外情況,鍵可以使用任意UTF-8字符。 文檔鍵命名規范: #1、鍵不能含有\0 (空字符)。這個字符用來表示鍵的結尾。 #2、.和$有特別的意義,只有在特定環境下才能使用。 #3、以下划線"_"開頭的鍵是保留的(不是嚴格要求的)。

2、集合就是一組文檔。如果將MongoDB中的一個文檔比喻為關系型數據的一行,那么一個集合就是相當於一張表

#1、集合存在於數據庫中,通常情況下為了方便管理,不同格式和類型的數據應該插入到不同的集合,但其實集合沒有固定的結構,這意味着我們完全可以把不同格式和類型的數據統統插入一個集合中。 #2、組織子集合的方式就是使用“.”,分隔不同命名空間的子集合。 比如一個具有博客功能的應用可能包含兩個集合,分別是blog.posts和blog.authors,這是為了使組織結構更清晰,這里的blog集合(這個集合甚至不需要存在)跟它的兩個子集合沒有任何關系。 在MongoDB中,使用子集合來組織數據非常高效,值得推薦 #3、當第一個文檔插入時,集合就會被創建。合法的集合名: 集合名不能是空字符串""。 集合名不能含有\0字符(空字符),這個字符表示集合名的結尾。 集合名不能以"system."開頭,這是為系統集合保留的前綴。 用戶創建的集合名字不能含有保留字符。有些驅動程序的確支持在集合名里面包含,這是因為某些系統生成的集合中包含該字符。除非你要訪問這種系統創建的集合,否則千萬不要在名字里出現$。

 3、數據庫:在MongoDB中,多個文檔組成集合,多個集合可以組成數據庫

數據庫也通過名字來標識。數據庫名可以是滿足以下條件的任意UTF-8字符串: #1、不能是空字符串("")。 #2、不得含有' '(空格)、.、$、/、\和\0 (空字符)。 #3、應全部小寫。 #4、最多64字節。 有一些數據庫名是保留的,可以直接訪問這些有特殊作用的數據庫。 #1、admin: 從身份認證的角度講,這是“root”數據庫,如果將一個用戶添加到admin數據庫,這個用戶將自動
獲得所有數據庫的權限。再者,一些特定的服務器端命令也只能從admin數據庫運行,如列出所有數據庫或關閉服務器 #
2、local: 這個數據庫永遠都不可以復制,且一台服務器上的所有本地集合都可以存儲在這個數據庫中 #3、config: MongoDB用於分片設置時,分片信息會存儲在config數據庫中

4、強調:把數據庫名添加到集合名前,得到集合的完全限定名,即命名空間

例如:
如果要使用cms數據庫中的blog.posts集合,這個集合的命名空間就是
cmd.blog.posts。命名空間的長度不得超過121個字節,且在實際使用中應該小於100個字節

三.MongoDB的安裝與使用

01】windows下安裝首先去官網下載: https://www.mongodb.com/dr/fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-ssl-3.4.4-signed.msi/download
02】下載后安裝,安裝完畢后,將bin目錄配置到系統的環境變量中去 【03】進入到安裝目錄下新建文件夾: 首先新建一個data目錄: D:\ProfessionalSoftwares\mongodb\data 然后在data目錄下新建兩個文件夾:db和logs 最后在logs目錄下新建一個文件:mongo.log 【04】現在我們將mongoDB做成一個服務然后在后台運行,這樣我們每次開機就可以使用MongoDB服務端了: 首先以管理員身份運行cmd命令行,然后在命令行中執行如下的命令:(因為我配置了環境變量,所以可以直接使用 mongod命令) mongod --bind_ip 0.0.0.0 --logpath D:\ProfessionalSoftwares\mongodb\data\logs\mongo.log
--logappend --dbpath D:\ProfessionalSoftwares\mongodb\data\db --port 27017
--serviceName "MongoDB" --serviceDisplayName "MongoDB" --install --auth 上述--install參數表示將mongodb作為一個服務進行安裝,--auth表示我客戶端鏈接mongodb服務端時,需要輸入指定的用戶名和密碼 安裝完畢后,然后在剛才開啟的管理員cmd命令行中啟動MongoDB服務: net start MongoDB 這里的MongoDB就是上面命令中的服務名:serviceName 另外如果需要關閉MongoDB這個服務,只需要使用net stop MongoDB即可 【05】最終操作完畢后,我們在瀏覽器中輸入如下的網址:http://localhost:27017/ 顯示這句話就表示我們安裝成功:
It looks like you are trying to access MongoDB over HTTP on the native driver port.

2.賬號管理

數據庫一般都是有相應的賬號和密碼的,MongoDB也有:

#賬號管理,參考官網地址:https://docs.mongodb.com/master/tutorial/enable-authentication/
 #1、創建賬號,這里我們相當於創建了一個管理員賬號root,然后在使用Robomongo登入數據庫時,需要輸入驗證, 要不然會報錯:Failed to execute "listdatabases" command. 筆者在這里坑了好久 默認情況下,MongoDB存在兩個數據庫:admin和test,我們創建管理員賬戶時,一般都在admin數據庫下 注意下面的步驟,都是需要在管理員權限的cmd命令行下執行: 接着上面的說,在初始環境下登入到MongoDB數據庫后,我們直接使用admin數據庫,然后創建賬號 use admin db.createUser( { user: "root", pwd: "cisco123", roles: [ { role: "root", db: "admin" } ] } ) #2、重啟數據庫 創建完管理員賬號和密碼后,我們首先退出MongoDb數據庫,然后將剛才安裝的MongoDB數據庫服務移除: 先關閉服務:net stop MongoDB 然后刪除: mongod --remove 移除后,我們再來重新安裝服務,這次安裝我們加入了--auth參數, 該參數表示,下次客戶端連接MongoDB數據庫時候,需要輸入用戶名和密碼,如下所示: mongod --bind_ip 0.0.0.0 --logpath D:\ProfessionalSoftwares\mongodb\data\logs\mongo.log --logappend --dbpath D:\ProfessionalSoftwares\mongodb\data\db --port 27017 --serviceName "MongoDB" --serviceDisplayName "MongoDB"  --install  --auth 然后再來重啟服務: net start MongoDB 現在我們來使用賬號和密碼登入MongoDB數據庫,注意后面我們需要指定相應的數據庫名稱:admin 因為我們的管理員賬號和密碼是在admin數據庫下新建的: #3、登錄:注意使用雙引號而非單引號 mongo --port 27017 -u "root" -p "cisco123" --authenticationDatabase "admin" 也可以在登錄之后用db.auth("賬號","密碼")登錄 mongo use admin db.auth("root","cisco123") 關於MongoDB的詳細信息可以關注這篇博客: #推薦博客:https://www.cnblogs.com/zhoujinyi/p/4610050.html

四 MongoDB的基本數據類型

1、在概念上,MongoDB的文檔與Javascript的對象相近,因而可以認為它類似於JSON。
JSON(http://www.json.org)是一種簡單的數據表示方式:其規范僅用一段文字就能描述清楚(其官網證明了這點),且僅包含六種數據類型。 2、這樣有很多好處:易於理解、易於解析、易於記憶。然而從另一方面說,因為只有null、布爾、數字、字符串、
數字和對象這幾種數據類型,所以JSON的表達能力有一定的局限。
3、雖然JSON具備的這些類型已經具有很強的表現力,但絕大數應用(尤其是在於數據庫打交道時)都還需要其他一些重要的類型。
例如,JSON沒有日期類型,這使得原本容易日期處理變得煩人。另外,JSON只有一種數字類型,無法區分浮點數和整數,更別區分32位和64位了。再者JSON無法表示其他一些通用類型,如正則表達式或函數。
4、MongoDB在保留了JSON基本鍵/值對特性的基礎上,添加了其他一些數據類型。在不同的編程語言下,這些類型的確切表示有些許差異。下面說明了MongoDB支持的其他通用類型,以及如何使用它們

 MongoDB支持的通用數據類型:

#1null:用於表示空或不存在的字段 d={'x':null} #2、布爾型:true和false,注意這里的true和false都是小寫 d={'x':true,'y':false} #3、數值 整型和浮點型 d={'x':3,'y':3.1415926} #4、字符串 d={'x':'egon'} #5、日期 可以接收一個日期對象 d={'x':new Date()} d.x.getHours() #6、正則表達式 d={'pattern':/^egon.*?nb$/i} 正則寫在//內,后面的i代表: i 忽略大小寫 m 多行匹配模式 x 忽略非轉義的空白字符 s 單行匹配模式 #7、數組:數組中的元素可以是整數,也可以是字符串 d={'x':[1,'a','v']} #8、內嵌文檔,表示value也可以是一個文檔, 如下面所示,我想訪問country對應的value:user.addr.country即可: user={'name':'egon','addr':{'country':'China','city':'YT'}} user.addr.country #9、對象id:是一個12字節的ID,是文檔的唯一標識,不可變 d={'x':ObjectId()}

例如我使用MongoDB中的數據類型來定義一個用戶記錄:

 

{"_id":ObjectId(),"name":'carson','is_admin':true, 'age':18,'salary':18000, 'hobbies':[1,'a'], 'comments':null}

 

5、_id和ObjectId

五 CRUD操作

1、數據庫操作(增刪改查)

#1、新增數據庫,需要說明的是,這里不需要像Mysql數據庫那樣判斷下數據庫是否存在 #如果數據庫config不存在,則創建數據庫config;如果存在,那就切換到該數據庫 這里使用use來新增數據庫 use config #2、查 show dbs #查看所有的數據庫 可以看到,我們剛創建的數據庫config並不在數據庫的列表中, MongoDB數據庫和其他的不一樣,如果一個新的數據庫中沒有任何集合,那么就不會展示它, 為了顯示該數據庫,我們需要向config數據庫插入一些數據。 db.table1.insert({'a':1}) 然后再來查詢: 細心的你可能發現了,我們並沒有給config數據庫建立表結構,那為什么這里可以使用table1 原因在於mongodb壓根不需要建立表,因為它根本沒有表結構,我們往表中插入數據時,這個表就自動建立起來了 > db.table1.insert({'a':1}) WriteResult({ "nInserted" : 1 }) > show dbs admin 0.000GB config 0.000GB database1 0.000GB local 0.000GB test 0.000GB 3.查看當前使用的數據庫:db 一旦你登入mongodb,那么就會給db賦予一個默認值,默認是test數據庫,即你默認是在test數據庫下面 這樣的好處在於,不管我們怎么切換數據,如果需要對該數據庫進行操作,那我們只需要使用db來代表當前的數據庫即可:因此use config 相當於 db=test > db database1 > use test switched to db test > db test > #4、刪除數據庫, use config #先切換到要刪的庫下 db.dropDatabase() #刪除當前庫 如下所示: > db config > db.dropDatabase() { "dropped" : "config", "ok" : 1 } >

5.另外如果我們需要查看數據庫有哪些操作方法,直接使用db.help()即可:

2、集合操作(類似於Mysql中的表操作)

當我們討論集合操作,其實就相當於討論的是關系型數據庫中的表操作,因為兩者是對應的:

#1、增 當第一個文檔插入時,集合就會被創建 > use database1 switched to db database1 > db.table1.insert({'a':1}) WriteResult({ "nInserted" : 1 }) > db.table2.insert({'b':1}) WriteResult({ "nInserted" : 1 }) > # 查詢數據庫database1下面的表有哪幾張,其實質就是查詢數據庫下的集合有哪些 > show tables; table1 table2 # 刪除表中的集合,使用drop() > db.table1.drop() true

> show tables; table2 >

我們在為MongoDB中的表命名時候,需要按照一定的規則聯系起來,如下圖所示:
例如我們之間所做的博客系統,有用戶表和評論表,我們使用外鍵將它們倆關聯起來,但是在
MongoDB中,我們直接使用.的方式即可關聯起來:
db.blog.user.inser()
db.blog.comments.insert()

在前面我們說過,MongoDB中默認會為我們的每條記錄新增一個"_id"字段,該字段用來唯一標識某個集合中的一條文檔,我們也可以自定義id屬性,不過要注意,自定義時,這個字段要叫做 _id,如下所示:

> db.emp.insert({'_id':1, 'name': 'carson'}) # 自定義屬性 WriteResult({ "nInserted" : 1 }) > db.emp.findOne() { "_id" : 1, "name" : "carson" } > db.emp.insert({'name':'alex'}) WriteResult({ "nInserted" : 1 }) > db.emp.find() { "_id" : 1, "name" : "carson" } { "_id" : ObjectId("5a5c5d5d8c6f3bc41b4589b2"), "name" : "alex" } > db.emp.insert({'name':'eva','salary':18000}) WriteResult({ "nInserted" : 1 }) > db.emp.find() { "_id" : 1, "name" : "carson" } { "_id" : ObjectId("5a5c5d5d8c6f3bc41b4589b2"), "name" : "alex" } { "_id" : ObjectId("5a5c5dfb8c6f3bc41b4589b3"), "name" : "eva", "salary" : 18000 } > db.emp.insert({'_id':1001, 'name': 'alex666'}) WriteResult({ "nInserted" : 1 }) > db.emp.find() { "_id" : 1, "name" : "carson" } { "_id" : ObjectId("5a5c5d5d8c6f3bc41b4589b2"), "name" : "alex" } { "_id" : ObjectId("5a5c5dfb8c6f3bc41b4589b3"), "name" : "eva", "salary" : 18000 } { "_id" : 1001, "name" : "alex666" }

3、文檔操作

新增文檔(新增記錄)

#創建一個user的局部變量,這是一個JavaScript對象 user={ "name":"carson", 'is_nb':true, 'hobbies':['music','read','dancing'] } db.userinfo.insert(user) db.userinfo.find() user1={ "name":"tom", 'is_sb':true, 'hobbies':['music','read','dancing'] } user2={ "name":"eva", 'is_sb':'wxx', 'hobbies':['music','read','dancing'] } user3={ "name":"carson666", 'is_sb':false, 'hobbies':['music','read','dancing'] } # 一次性插入多條記錄(文檔) db.userinfo.insertMany([user1,user2,user3])

當我們查詢記錄時,如果想讓查詢結果更好的展示,使用pretty()方法即可:

 

 修改文檔:

update() 方法用於更新已存在的文檔。語法格式如下: db.collection.update( <query>, <update>, { upsert: <boolean>, multi: <boolean>, writeConcern: <document> } ) 參數說明:對比update db1.t1 set name='EGON',sex='Male' where name='egon' and age=18; query : 相當於where條件。 update : update的對象和一些更新的操作符(如$,$inc...等,相當於set后面的 upsert : 可選,默認為false,代表如果不存在update的記錄不更新也不插入,設置為true代表插入。 multi : 可選,默認為false,代表只更新找到的第一條記錄,設為true,代表更新找到的全部記錄。 writeConcern :可選,拋出異常的級別。 更新操作是不可分割的:若兩個更新同時發送,先到達服務器的先執行,然后執行另外一個,不會破壞文檔。

對文檔的更新,我們使用.來進行操作:首先找到要更新的對象,然后使用.取出文檔對應的屬性,來看下面的例子:

# 先找到要修改的文檔對象 carson 使用var關鍵字聲明 > var carson=db.userinfo.findOne({'name':'carson'}) > carson { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "name" : "carson", "is_nb" : true, "hobbies" : [ "music", "read", "dancing" ] } # 為carson文檔對象新增一個屬性relationship,其對應的值為:{'girl_friends':33,'wives':23} 可以看到value對應的值類型又可以是一個文檔 > carson.relationship={'girl_friends':33,'wives':23} { "girl_friends" : 33, "wives" : 23 } > carson { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "name" : "carson", "is_nb" : true, "hobbies" : [ "music", "read", "dancing" ], "relationship" : { "girl_friends" : 33, "wives" : 23 } } # 為carson文檔對象新增一個屬性username,其值為carson.name > carson.username=carson.name carson > carson { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "name" : "carson", "is_nb" : true, "hobbies" : [ "music", "read", "dancing" ], "relationship" : { "girl_friends" : 33, "wives" : 23 }, "username" : "carson" } > carson.girl_friends=33
33
> carson { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "name" : "carson", "is_nb" : true, "hobbies" : [ "music", "read", "dancing" ], "relationship" : { "girl_friends" : 33, "wives" : 23 }, "username" : "carson", "girl_friends" : 33 } > carson.wives = 23
23
> carson { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "name" : "carson", "is_nb" : true, "hobbies" : [ "music", "read", "dancing" ], "relationship" : { "girl_friends" : 33, "wives" : 23 }, "username" : "carson", "girl_friends" : 33, "wives" : 23 } # 刪掉沒有用的 > delete carson.relationship true
> carson { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "name" : "carson", "is_nb" : true, "hobbies" : [ "music", "read", "dancing" ], "username" : "carson", "girl_friends" : 33, "wives" : 23 }

我們來看下面一個常見的更新錯誤:

 

現在我們往集合userinfo中新增三個文檔對象,每個文檔對象中的用戶名剛好相同 db.userinfo.insert({'name':'angina','age':10}) db.userinfo.insert({'name':'angina','age':20}) db.userinfo.insert({'name':'angina','age':30}) > db.userinfo.find() { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "name" : "carson", "is_nb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b5"), "name" : "tom", "is_sb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b6"), "name" : "eva", "is_sb" : "wxx", "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b7"), "name" : "carson666", "is_sb" : false, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b8"), "name" : "angina", "age" : 10 } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b9"), "name" : "angina", "age" : 20 } { "_id" : ObjectId("5a5c6a6e8c6f3bc41b4589ba"), "name" : "angina", "age" : 30 } # 找到的是第二個angina,他要過生日,於是長了一歲 > var angina = db.userinfo.findOne({'name':'angina', 'age':20}) > angina.age++
20 # 發現angina這條文檔對象對應的age屬性自增了1歲 > angina { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b9"), "name" : "angina", "age" : 21 } # 但是我們發現原始集合中的userinfo並沒有任何改變,還是20歲,所以我們取出來修改后,最后 # 還要更新到集合中才算正式修改 > db.userinfo.find() { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "name" : "carson", "is_nb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b5"), "name" : "tom", "is_sb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b6"), "name" : "eva", "is_sb" : "wxx", "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b7"), "name" : "carson666", "is_sb" : false, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b8"), "name" : "angina", "age" : 10 } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b9"), "name" : "angina", "age" : 20 } { "_id" : ObjectId("5a5c6a6e8c6f3bc41b4589ba"), "name" : "angina", "age" : 30 } # 將修改的變化同步更新到userinfo集合中,我們的條件只定位到第二條記錄這一條記錄,所以更新是沒問題的, > db.userinfo.update({'name':'angina', 'age':20},angina) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) # 然后再來查看,發現修改成功 > db.userinfo.find() { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "name" : "carson", "is_nb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b5"), "name" : "tom", "is_sb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b6"), "name" : "eva", "is_sb" : "wxx", "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b7"), "name" : "carson666", "is_sb" : false, "hobbies" : [ "music", "read", "dancing" ] }suo'y
{ "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b8"), "name" : "angina", "age" : 10 } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b9"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6e8c6f3bc41b4589ba"), "name" : "angina", "age" : 30 } # 這里我們僅僅是按照name來匹配集合中的文檔,這里匹配到了三條,但MongoDB是沒辦法將 # 三條文檔對象都修改成同一個_id,zheli > db.userinfo.update({'name':'angina'}, obj) 2018-01-15T16:57:08.822+0800 E QUERY    [thread1] ReferenceError: obj is not defined : @(shell):1:21 # 刪除掉angina文檔對象的ID > delete angina._id true
> angina { "name" : "angina", "age" : 21 } # 此時集合中的文檔對象信息如下所示: > db.userinfo.find() { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "name" : "carson", "is_nb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b5"), "name" : "tom", "is_sb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b6"), "name" : "eva", "is_sb" : "wxx", "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b7"), "name" : "carson666", "is_sb" : false, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b8"), "name" : "angina", "age" : 10 } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b9"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6e8c6f3bc41b4589ba"), "name" : "angina", "age" : 30 } # 此時再來更新,發現居然更新成功 > db.userinfo.update({"name":"angina"},angina) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) # 我們查詢,發現此時更新的是第一條 > db.userinfo.find() { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "name" : "carson", "is_nb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b5"), "name" : "tom", "is_sb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b6"), "name" : "eva", "is_sb" : "wxx", "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b7"), "name" : "carson666", "is_sb" : false, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b8"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b9"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6e8c6f3bc41b4589ba"), "name" : "angina", "age" : 30 } # 針對這種情況,我們還是以id來選中第二條記錄 > db.userinfo.update({"_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b9")}, angina) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) # 由於此時angina文檔對象的age依然為21,所以在集合中同步更新后,依然也是21 > db.userinfo.find() { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "name" : "carson", "is_nb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b5"), "name" : "tom", "is_sb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b6"), "name" : "eva", "is_sb" : "wxx", "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b7"), "name" : "carson666", "is_sb" : false, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b8"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b9"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6e8c6f3bc41b4589ba"), "name" : "angina", "age" : 30 } > # 現在我想更新多條,即將name屬性值為angina的文檔對象的age屬性都更新為21,怎么辦?使用multi:true關鍵字即可 >
> db.userinfo.update({"name":'angina'}, angina, {'multi':true}) WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 9, "errmsg" : "multi update only works with $ operators" # 提示報錯,只能用修改器 } })

 

接着上面的,我們使用$set:angina來結合multi:true即可完成修改,不過這里的前提是將angina文檔對象的id刪除了

> db.userinfo.update({"name":'angina'}, {$set:angina}, {'multi':true}) WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 1 }) > db.userinfo.find() { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "name" : "carson", "is_nb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b5"), "name" : "tom", "is_sb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b6"), "name" : "eva", "is_sb" : "wxx", "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b7"), "name" : "carson666", "is_sb" : false, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b8"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b9"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6e8c6f3bc41b4589ba"), "name" : "angina", "age" : 21 }

 

 

六.使用修改器

 

db.users.insert({'name':'angina','age':10}) db.users.insert({'name':'angina','age':20}) db.users.insert({'name':'angina','age':30}) 1"$set"修改器 > db.users.find() { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "name" : "angina", "age" : 10 } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "angina", "age" : 20 } { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "angina", "age" : 30 } > db.users.update({'_id': ObjectId("5a5c83c48c6f3bc41b4589be")},{'age':111}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) """ 完全覆蓋了原文檔: 原來的文檔對象是:"_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "name" : "angina", "age" : 10 現在變為:"_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "age" : 111
""" > db.users.find() { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "age" : 111 } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "angina", "age" : 20 } { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "angina", "age" : 30 } """ 使用#$set只更新原文檔的一部分 原來是"_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "angina", "age" : 20 現在變為:"_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "angina", "age" : 222 $set對應的value為要修改的目標的值 """ > db.users.update({'_id':ObjectId("5a5c83c48c6f3bc41b4589bf")},{'$set':{'age':222}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.users.find() { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "age" : 111 } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "angina", "age" : 222 } { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "angina", "age" : 30 } # 現在往原始集合中再添加一條文檔 > db.users.insert({'name':'angina','age':40,'addr':{'country':'China','city':'BJ'}}) WriteResult({ "nInserted" : 1 }) > db.users.find() { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "age" : 111 } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "angina", "age" : 222 } { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "angina", "age" : 30 } { "_id" : ObjectId("5a5c854e8c6f3bc41b4589c1"), "name" : "angina", "age" : 40, "addr" : { "country" : "China", "city" : "BJ" } } # 接着再添加一條: > db.users.insert({'name':'angina','age':50,'addr':{'country':'USA','city':'ShangHai'}}) WriteResult({ "nInserted" : 1 }) > db.users.find() { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "age" : 111 } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "angina", "age" : 222 } { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "angina", "age" : 30 } { "_id" : ObjectId("5a5c854e8c6f3bc41b4589c1"), "name" : "angina", "age" : 40, "addr" : { "country" : "China", "city" : "BJ" } } { "_id" : ObjectId("5a5c856d8c6f3bc41b4589c2"), "name" : "angina", "age" : 50, "addr" : { "country" : "USA", "city" : "ShangHai" } } > db.users.find() { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "age" : 111 } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "angina", "age" : 222 } { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "angina", "age" : 30 } { "_id" : ObjectId("5a5c854e8c6f3bc41b4589c1"), "name" : "angina", "age" : 40, "addr" : { "country" : "China", "city" : "BJ" } } { "_id" : ObjectId("5a5c856d8c6f3bc41b4589c2"), "name" : "angina", "age" : 50, "addr" : { "country" : "USA", "city" : "ShangHai" } } """ 這里我本來想做的是對name為angina的文檔對象,將他們的addr值修改為:{'country':'China','city':'BJ'} 但實際上只是修改了匹配的第一條,那如果我想修改所有的怎么辦? """ > db.users.update({"name":"angina"},{'$set':{'addr':{'country':'China','city':'BJ'}}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.users.find() { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "age" : 111 } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "angina", "age" : 222, "addr" : { "country" : "China", "city" : "BJ" } } { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "angina", "age" : 30 } { "_id" : ObjectId("5a5c854e8c6f3bc41b4589c1"), "name" : "angina", "age" : 40, "addr" : { "country" : "China", "city" : "BJ" } } { "_id" : ObjectId("5a5c856d8c6f3bc41b4589c2"), "name" : "angina", "age" : 50, "addr" : { "country" : "USA", "city" : "ShangHai" } } """ 下面的操作就是將age為30歲的文檔對象添加一個addr屬性,因為該文檔對象並沒有addr屬性,所以這里默認就是新增了 """ > db.users.update({'age':30},{'$set':{'addr':{'country':'China','city':'BJ'}}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.users.find() { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "age" : 111 } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "angina", "age" : 222, "addr" : { "country" : "China", "city" : "BJ" } } { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "angina", "age" : 30, "addr" : { "country" : "China", "city" : "BJ" } } { "_id" : ObjectId("5a5c854e8c6f3bc41b4589c1"), "name" : "angina", "age" : 40, "addr" : { "country" : "China", "city" : "BJ" } } { "_id" : ObjectId("5a5c856d8c6f3bc41b4589c2"), "name" : "angina", "age" : 50, "addr" : { "country" : "USA", "city" : "ShangHai" } } """ 將age為50的文檔對象為的地址修改為:{'country':'China','city':'BJ'} 原來是{ "country" : "USA", "city" : "ShangHai" } 因此可以總結:update結合$set的使用原則: 如果對應的文檔對象中有這個屬性,那么就再修改,沒有就添加 """ db.users.update({'age':50},{'$set':{'addr':{'country':'China','city':'BJ'}}}) # 下面就是修改內嵌文檔,所謂內嵌文檔,即value的類型是一個字典(又是一個文檔對象) 這里是將age為30的文檔對象的addr屬性對應的country屬性值修改為CHINA 原來是China ,現在變成了CHINA >
> db.users.update({'age':30},{'$set':{'addr.country':'CHINA'}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.users.find() { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "age" : 111 } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "angina", "age" : 222, "addr" : { "country" : "China", "city" : "BJ" } } { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "angina", "age" : 30, "addr" : { "country" : "CHINA", "city" : "BJ" } } { "_id" : ObjectId("5a5c854e8c6f3bc41b4589c1"), "name" : "angina", "age" : 40, "addr" : { "country" : "China", "city" : "BJ" } } { "_id" : ObjectId("5a5c856d8c6f3bc41b4589c2"), "name" : "angina", "age" : 50, "addr" : { "country" : "USA", "city" : "ShangHai" } } >

""" 這里的unset相當於就是將addr對應的鍵和值給清空掉 原來是 { "_id" : ObjectId("5a5c854e8c6f3bc41b4589c1"), "name" : "angina", "age" : 40, "addr" : { "country" : "China", "city" : "BJ" } } 現在是 { "_id" : ObjectId("5a5c854e8c6f3bc41b4589c1"), "name" : "angina", "age" : 40 } """"
> db.users.update({'age':40},{'$unset':{'addr':'umpty'}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.users.find() { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "age" : 111 } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "angina", "age" : 222, "addr" : { "country" : "China", "city" : "BJ" } } { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "angina", "age" : 30 } { "_id" : ObjectId("5a5c854e8c6f3bc41b4589c1"), "name" : "angina", "age" : 40 } { "_id" : ObjectId("5a5c856d8c6f3bc41b4589c2"), "name" : "angina", "age" : 50, "addr" : { "country" : "China", "city" : "BJ" } }

我們再通過一個需求來看看unset的作用:

db.user.insert( { "_id": ObjectId("521d9c18b34cd9052000000a"), "allylist": { "1987": { } }, "allyreq": { "1": true, "2": true, "3": true }, "energy": 100, "exp": 200, "formation": { "id": 0, "positionlist": [ NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0) ] }, "gold": 10000, "heroghost": 20000, "iconid": 1, "level": 10, "name": "cs9", "name2": "Roger", "name3": { "name": "Roger" }, "password": "123", "sex": 1, "userid": NumberLong(9) })

需求 :我現在想allyreq里面的1這個key和value都刪除掉,如下:

db.user.update({"userid":9},{"$unset":{"allyreq.1":true}})

再來查看,發現沒有了:

> db.user.find().pretty() { "_id" : ObjectId("521d9c18b34cd9052000000a"), "allylist" : { "1987" : { } }, "allyreq" : { "2" : true, "3" : true }, "energy" : 100, "exp" : 200, "formation" : { "id" : 0, "positionlist" : [ NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0) ] }, "gold" : 10000, "heroghost" : 20000, "iconid" : 1, "level" : 10, "name" : "cs9", "name2" : "Roger", "name3" : { "name" : "Roger" }, "password" : "123", "sex" : 1, "userid" : NumberLong(9) }

現在我想讓它還原,使用set即可:

> db.user.update({"userid":9},{"$set":{"allyreq.1":true}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.user.find().pretty() { "_id" : ObjectId("521d9c18b34cd9052000000a"), "allylist" : { "1987" : { } }, "allyreq" : { "2" : true, "3" : true, "1" : true # 注意這里是有序添加,自動添加到字典的后面 }, "energy" : 100, "exp" : 200, "formation" : { "id" : 0, "positionlist" : [ NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0), NumberLong(0) ] }, "gold" : 10000, "heroghost" : 20000, "iconid" : 1, "level" : 10, "name" : "cs9", "name2" : "Roger", "name3" : { "name" : "Roger" }, "password" : "123", "sex" : 1, "userid" : NumberLong(9) }

3、往數組內添加元素

 

如果數組已經存在,"$push"會向已有的數組末尾加入一個元素,要是沒有就創建一個新的數組。 例如提交博客的評論 db.blog.insert({'_id':1,'name':'carson意外死亡的真相'}) db.blog.update({'_id':1},{'$push':{'comments':{"name":"egon","content":'alex是誰???'}}}) db.blog.update({'_id':1},{'$push':{'comments':{"name":"wxx","content":'我去,真的假的'}}}) db.blog.update({'_id':1},{'$push':{'comments':{"name":"yxx","content":'吃喝嫖賭抽,欠下兩個億'}}}) # 使用$each一次性添加多個評論文檔對象,多個評論文檔對象組成一個數組 db.blog.update({'_id':1},{'$push':{'comments':{'$each':[ {'name':'xxx','content':'二鞠躬'}, {'name':'yyy','content':'三鞠躬'}, {'name':'yyy','content':'四鞠躬'}, {'name':'zzz','content':'五鞠躬'}, {'name':'mmm','content':'六鞠躬'}, {'name':'nnn','content':'七鞠躬'}, ]}}}) # 一次性添加完畢一個文檔對象數組,然后截取最后7條文檔對象 # 注意這里截取完畢后,我們再來打印db.blog.find()獲取的就是最后7條文檔對象了 db.blog.update({'_id':1},{'$push':{'comments':{'$each':[ {'name':'xxx','content':'二鞠躬'}, {'name':'yyy','content':'三鞠躬'}, {'name':'yyy','content':'四鞠躬'}, {'name':'zzz','content':'五鞠躬'}, {'name':'mmm','content':'六鞠躬'}, {'name':'nnn','content':'七鞠躬'}, ], '$slice':-7 }}}) > db.blog.insert({'_id':1,'name':'carson意外死亡的真相'}) WriteResult({ "nInserted" : 1 }) > db.blog.find() { "_id" : 1, "name" : "carson意外死亡的真相" } > db.blog.update({'_id':1},{'$push':{'comments':{"name":"egon","content":'alex是誰???'}}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.blog.update({'_id':1},{'$push':{'comments':{"name":"wxx","content":'我去,真的假的'}}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.blog.update({'_id':1},{'$push':{'comments':{"name":"yxx","content":'吃喝嫖賭抽,欠下兩個億'}}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.blog.find().pretty() { "_id" : 1, "name" : "carson意外死亡的真相", "comments" : [ { "name" : "egon", "content" : "alex是誰???" }, { "name" : "wxx", "content" : "我去,真的假的" }, { "name" : "yxx", "content" : "吃喝嫖賭抽,欠下兩個億" } ] } > db.blog.update({'_id':1},{'$push':{'comments':{'$each':[{'name':'oldboy','content':'鼓掌'},{'name':'oldgirl','content':'一鞠躬'}]}}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.blog.find().pretty() { "_id" : 1, "name" : "carson意外死亡的真相", "comments" : [ { "name" : "egon", "content" : "alex是誰???" }, { "name" : "wxx", "content" : "我去,真的假的" }, { "name" : "yxx", "content" : "吃喝嫖賭抽,欠下兩個億" }, { "name" : "oldboy", "content" : "鼓掌" }, { "name" : "oldgirl", "content" : "一鞠躬" } ] } # 使用$each一次性添加多個評論文檔對象,多個評論文檔對象組成一個數組 > db.blog.update({'_id':1},{'$push':{'comments':{'$each':[ ... {'name':'xxx','content':'二鞠躬'}, ... {'name':'yyy','content':'三鞠躬'}, ... {'name':'yyy','content':'四鞠躬'}, ... {'name':'zzz','content':'五鞠躬'}, ... {'name':'mmm','content':'六鞠躬'}, ... {'name':'nnn','content':'七鞠躬'}, ... ]}}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.blog.find().pretty() { 七鞠躬'}, ]}}})
        "_id" : 1, "name" : "carson意外死亡的真相", "comments" : [ { "name" : "egon", "content" : "alex是誰???" }, { "name" : "wxx", "content" : "我去,真的假的" }, { "name" : "yxx", "content" : "吃喝嫖賭抽,欠下兩個億" }, { "name" : "oldboy", "content" : "鼓掌" }, { "name" : "oldgirl", "content" : "一鞠躬" }, { "name" : "xxx", "content" : "二鞠躬" }, { "name" : "yyy", "content" : "三鞠躬" }, { "name" : "yyy", "content" : "四鞠躬" }, { "name" : "zzz", "content" : "五鞠躬" }, { "name" : "mmm", "content" : "六鞠躬" }, { "name" : "nnn", "content" : "七鞠躬" } ] } # 再繼續使用$each一次性添加六條評論,同時截取最后的7條評論,使用$slice來限制獲取的評論的條數
# 即通過該參數來限制大小,只保留最后n個文檔對象
> db.blog.update({'_id':1},{'$push':{'comments':{'$each':[ ... {'name':'xxx','content':'八鞠躬'}, ... {'name':'yyy','content':'九鞠躬'}, ... {'name':'yyy','content':'十鞠躬'}, ... {'name':'zzz','content':'十一鞠躬'}, ... {'name':'mmm','content':'十二鞠躬'}, ... {'name':'nnn','content':'十三鞠躬'}, ... ], ... '$slice':-7 ... }}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) # 注意這里截取完畢后,我們再來打印db.blog.find()獲取的就是最后7條文檔對象了 > db.blog.find().pretty() { "_id" : 1, "name" : "carson意外死亡的真相", "comments" : [ { "name" : "nnn", "content" : "七鞠躬" }, { "name" : "xxx", "content" : "八鞠躬" }, { "name" : "yyy", "content" : "九鞠躬" }, { "name" : "yyy", "content" : "十鞠躬" }, { "name" : "zzz", "content" : "十一鞠躬" }, { "name" : "mmm", "content" : "十二鞠躬" }, { "name" : "nnn", "content" : "十三鞠躬" } ] }

 

 

5、避免添加重復 "$addToSet"

#=======> 添加新的數組 > db.urls.insert({'_id':1,'urls':[]}) WriteResult({ "nInserted" : 1 }) > db.urls.insert({'_id':2,'urls':[]}) WriteResult({ "nInserted" : 1 }) > db.urls.find() { "_id" : 1, "urls" : [ ] } { "_id" : 2, "urls" : [ ] } # 使用$addToSet避免重復向urls對應的數組中重復添加元素,可以看到最終 # 我們打印的時候,結果是http://www.baidu.com這個域名被添加進去了1次
 db.urls.update({'_id':1},{'$addToSet':{'urls':'http://www.baidu.com'}}) db.urls.update({'_id':1},{'$addToSet':{'urls':'http://www.baidu.com'}}) db.urls.update({'_id':2},{'$addToSet':{'urls':'http://www.openstack.org'}}) db.urls.update({'_id':2},{'$addToSet':{'urls':'http://www.openstack.org'}}) db.urls.update({'_id':2},{'$addToSet':{'urls':'http://www.python.org'}}) # 然后再來查看 發現id為1的文檔對象中的urls對應的數組只有http://www.baidu.com
而id為2的文檔對象的urls對應的數組中有"http://www.openstack.org", "http://www.python.org" 這就是$addToSet的作用 > db.urls.find() { "_id" : 1, "urls" : [ "http://www.baidu.com" ] } { "_id" : 2, "urls" : [ "http://www.openstack.org", "http://www.python.org" ] } # 如果我們使用$each來批量添加域名,最終的結果也不會重復 db.urls.update({'_id':1},{ '$addToSet':{ 'urls':{ '$each':['www.openstack.org','www.openstack.org','http://www.xxx.com'] } } }) db.urls.update({'_id':2},{ '$addToSet':{ 'urls':{ '$each':['www.openstack.org','www.openstack.org','http://www.xxx.com'] } } }) 最后再來查詢下: > db.urls.find() { "_id" : 1, "urls" : [ "http://www.baidu.com", "www.openstack.org", "http://www.xxx.com" ] } { "_id" : 2, "urls" : [ "http://www.openstack.org", "http://www.python.org", "www.openstack.org", "http://www.xxx.com" ] } > 注意http://www.openstack.org和www.openstack.org是兩個不同的域名,不要搞混淆了

6.刪除元素

#=======>6、刪除元素 如果把數組看成是隊列或者棧,可以用"$pop",這個修改器可以從數組任何一端刪除元素。 {"$pop":{"key":1}} 從數組末尾刪除一個元素 {"$pop":{"key":-1}} 從頭部刪除 > db.queue.insert({'_id':1,'queue':[]}) WriteResult({ "nInserted" : 1 }) # 入隊列 db.queue.update({'_id':1},{'$push':{'queue':'alex'}}) db.queue.update({'_id':1},{'$push':{'queue':'egon'}}) db.queue.update({'_id':1},{'$push':{'queue':'wxx'}}) db.queue.update({'_id':1},{'$push':{'queue':'yxx'}}) > db.queue.find() { "_id" : 1, "queue" : [ "alex", "egon", "wxx", "yxx" ] } # 出隊列 db.queue.update({'_id':1},{"$pop":{"queue":-1}}) db.queue.update({'_id':1},{"$pop":{"queue":-1}}) db.queue.update({'_id':1},{"$pop":{"queue":-1}}) # 最終打印結果,可以發現這里出隊列是從頭部逐個刪除元素 > db.queue.find() { "_id" : 1, "queue" : [ "yxx" ] } # 我們再來新增id為2的文檔對象記錄: db.queue.insert({'_id':2,'queue':[]}) db.queue.update({'_id':2}, {'$push':{'queue': 'carson01'}}) db.queue.update({'_id':2}, {'$push':{'queue': 'carson02'}}) db.queue.update({'_id':2}, {'$push':{'queue': 'carson03'}}) # "$pull" 把符合條件的統統刪掉,而$pop只能按照位置刪除 db.queue.update({'_id':2},{"$pull":{"queue":'carson'}}) > db.queue.find() { "_id" : 1, "queue" : [ "yxx" ] } { "_id" : 2, "queue" : [ "carson01", "carson02", "carson03" ] }

7.基於數組位置的修改器

#=======>7、基於位置的數組修改器 db.blogcomment.insert({'_id':1,'name':'alex意外死亡的真相'}) db.blogcomment.update({'_id':1},{'$push':{'comments':{"name":"egon","content":'alex是誰???','thumb':20}}}) db.blogcomment.update({'_id':1},{'$push':{'comments':{"name":"wxx","content":'我去,真的假的','thumb':30}}}) db.blogcomment.update({'_id':1},{'$push':{'comments':{"name":"yxx","content":'吃喝嫖賭抽,欠下兩個億','thumb':40}}}) > db.blogcomment.find().pretty() { "_id" : 1, "name" : "alex意外死亡的真相", "comments" : [ { "name" : "egon", "content" : "alex是誰???", "thumb" : 20 }, { "name" : "wxx", "content" : "我去,真的假的", "thumb" : 30 }, { "name" : "yxx", "content" : "吃喝嫖賭抽,欠下兩個億", "thumb" : 40 } ] } 根據下標修改 db.blogcomment.update({'_id':1},{'$set':{'comments.0.thumb':666}}) # 然后再來查詢下: > db.blogcomment.find().pretty() { "_id" : 1, "name" : "alex意外死亡的真相", "comments" : [ { "name" : "egon", "content" : "alex是誰???", "thumb" : 666 # 變成了666,原來是20 }, { "name" : "wxx", "content" : "我去,真的假的", "thumb" : 30 }, { "name" : "yxx", "content" : "吃喝嫖賭抽,欠下兩個億", "thumb" : 40 } ] } 使用$,$代表根據條件匹配出的元素 相當於$代表的是前面匹配出的某條文檔對象,例如我們通過'comments.name':'wxx' 可以匹配出的文檔對象為 { "name" : "wxx", "content" : "我去,真的假的", "thumb" : 30 } 此時$就代表匹配出的這個文檔對象,然后通過.的方式來修改該文檔對象的thumb屬性值 db.blogcomment.update({'comments.name':'wxx'},{'$set':{'comments.$.thumb':999}}) > db.blogcomment.find().pretty() { "_id" : 1, "name" : "alex意外死亡的真相", "comments" : [ { "name" : "egon", "content" : "alex是誰???", "thumb" : 666 }, { "name" : "wxx", "content" : "我去,真的假的", "thumb" : 999 }, { "name" : "yxx", "content" : "吃喝嫖賭抽,欠下兩個億", "thumb" : 40 } ] } >

接着來看查詢操作:

# SQL:=,!=,>,<,>=,<= # MongoDB:{key:value}代表什么等於什么,"$ne","$gt","$lt","gte","lte",其中"$ne"能用於所有數據類型,其表示不等於 #1select * from db1.user where name = "alex"; db.user.find({'name':'alex'}) #2select * from db1.user where name != "alex"; db.user.find({'name':{"$ne":'alex'}}) #3select * from db1.user where id > 2; db.user.find({'_id':{'$gt':2}}) #4select * from db1.user where id < 3; db.user.find({'_id':{'$lt':3}}) #5select * from db1.user where id >= 2; db.user.find({"_id":{"$gte":2,}}) #6select * from db1.user where id <= 2; db.user.find({"_id":{"$lte":2}})

我們以集合users為例來練習幾個上面的示例:

找出users集合中age>=30,<=50的文檔對象 db.users.find({"age":{"$gte":30, "$lte":50}})

接下來我們看看MongoDB中的邏輯運算:

# SQL:and,or,not # MongoDB:字典中逗號分隔的多個條件是and關系"$or"的條件放到[]內,"$not" #1select * from db1.user where id >= 2 and id < 4; db.user.find({'_id':{"$gte":2,"$lt":4}}) #2select * from db1.user where id >= 2 and age < 40; db.user.find({"_id":{"$gte":2},"age":{"$lt":40}}) #3select * from db1.user where id >= 5 or name = "alex"; db.user.find({ # or的條件放到數組內 "$or":[ {'_id':{"$gte":5}}, {"name":"alex"} ] }) # 取出id值與2取余為1的文檔對象 #4select * from db1.user where id % 2=1; db.user.find({'_id':{"$mod":[2,1]}}) #5、上題,取反 db.user.find({'_id':{"$not":{"$mod":[2,1]}}})

成員匹配in和not in:

# SQL:in,not in # MongoDB:"$in","$nin" #1select * from db1.user where age in (20,30,31); db.user.find({"age":{"$in":[20,30,31]}}) #2select * from db1.user where name not in ('alex','yuanhao'); db.user.find({"name":{"$nin":['alex','yuanhao']}})

MongoDB中的正則表達式匹配:

# SQL: regexp 正則 # MongoDB: /正則表達/i #1select * from db1.user where name regexp '^j.*?(g|n)$'; db.user.find({'name':/^j.*?(g|n)$/i})

例如找到userinfo表中name以c開頭的姓名:

> db.userinfo.find({'name':/^c.*?/i}) { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "name" : "carson", "is_nb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b7"), "name" : "carson666", "is_sb" : false, "hobbies" : [ "music", "read", "dancing" ] } >

獲取集合中文檔對象的指定字段:

#1select name,age from db1.user where id=3; db.user.find({'_id':3},{'_id':0,'name':1,'age':1})

記住,一旦涉及到條件的篩選,那就需要單獨將條件表達式寫到一個字典中:{'id':3}

查詢數組,首先修改我們原始的userinfo集合如下:

> db.userinfo.find() { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "name" : "carson", "is_nb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b5"), "name" : "tom", "is_sb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b6"), "name" : "eva", "is_sb" : "wxx", "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b7"), "name" : "carson666", "is_sb" : false, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b8"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b9"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6e8c6f3bc41b4589ba"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c837a8c6f3bc41b4589bb"), "name" : "angina", "age" : 10 } { "_id" : ObjectId("5a5c837a8c6f3bc41b4589bc"), "name" : "angina", "age" : 20 } { "_id" : ObjectId("5a5c837b8c6f3bc41b4589bd"), "name" : "angina", "age" : 30 } # 修改name為carson的文檔對象對應的hobbies > db.userinfo.update({'name':'carson'},{"hobbies": ["tea", "singing"]}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.userinfo.find() { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "hobbies" : [ "tea", "singing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b5"), "name" : "tom", "is_sb" : true, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b6"), "name" : "eva", "is_sb" : "wxx", "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b7"), "name" : "carson666", "is_sb" : false, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b8"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b9"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6e8c6f3bc41b4589ba"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c837a8c6f3bc41b4589bb"), "name" : "angina", "age" : 10 } { "_id" : ObjectId("5a5c837a8c6f3bc41b4589bc"), "name" : "angina", "age" : 20 } { "_id" : ObjectId("5a5c837b8c6f3bc41b4589bd"), "name" : "angina", "age" : 30 } # 修改name為tom的文檔對象對應的hobbies > db.userinfo.update({'name':'tom'},{"hobbies": ["music", "read", "dancing","tea"]}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.userinfo.update({'name':'eva'},{"hobbies": [tea",]})
> db.userinfo.update({'name':'eva'},{"hobbies": ["tea",]}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.userinfo.find() { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "hobbies" : [ "tea", "singing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b5"), "hobbies" : [ "music", "read", "dancing", "tea" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b6"), "hobbies" : [ "tea" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b7"), "name" : "carson666", "is_sb" : false, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b8"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b9"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6e8c6f3bc41b4589ba"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c837a8c6f3bc41b4589bb"), "name" : "angina", "age" : 10 } { "_id" : ObjectId("5a5c837a8c6f3bc41b4589bc"), "name" : "angina", "age" : 20 } { "_id" : ObjectId("5a5c837b8c6f3bc41b4589bd"), "name" : "angina", "age" : 30 }

查找方法

> db.users.find({"age":{"$gt":30}}) { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "age" : 111 } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "angina", "age" : 222, "addr" : { "country" : "China", "city" : "BJ" } } { "_id" : ObjectId("5a5c854e8c6f3bc41b4589c1"), "name" : "angina", "age" : 40 } { "_id" : ObjectId("5a5c856d8c6f3bc41b4589c2"), "name" : "angina", "age" : 50, "addr" : { "country" : "China", "city" : "BJ" } } # 和上面的對比,查找匹配成功的第一條 > db.users.findOne({"age":{"$gt":30}}) { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "age" : 111 } >

 刪除集合中的文檔對象

> db.userinfo.find() { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "hobbies" : [ "tea", "singing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b5"), "hobbies" : [ "music", "read", "dancing", "tea" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b6"), "hobbies" : [ "tea" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b7"), "name" : "carson666", "is_sb" : false, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b8"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b9"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6e8c6f3bc41b4589ba"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c837a8c6f3bc41b4589bb"), "name" : "angina", "age" : 10 } { "_id" : ObjectId("5a5c837a8c6f3bc41b4589bc"), "name" : "angina", "age" : 20 } { "_id" : ObjectId("5a5c837b8c6f3bc41b4589bd"), "name" : "angina", "age" : 30 } #刪除匹配到的多個文檔對象中第一個,發現id為"5a5c6a6c8c6f3bc41b4589b8"這條文檔對象沒有了 > db.userinfo.deleteOne({'name':"angina"}) { "acknowledged" : true, "deletedCount" : 1 } > db.userinfo.find() { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "hobbies" : [ "tea", "singing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b5"), "hobbies" : [ "music", "read", "dancing", "tea" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b6"), "hobbies" : [ "tea" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b7"), "name" : "carson666", "is_sb" : false, "hobbies" : [ "music", "read", "dancing" ] } { "_id" : ObjectId("5a5c6a6c8c6f3bc41b4589b9"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c6a6e8c6f3bc41b4589ba"), "name" : "angina", "age" : 21 } { "_id" : ObjectId("5a5c837a8c6f3bc41b4589bb"), "name" : "angina", "age" : 10 } { "_id" : ObjectId("5a5c837a8c6f3bc41b4589bc"), "name" : "angina", "age" : 20 } { "_id" : ObjectId("5a5c837b8c6f3bc41b4589bd"), "name" : "angina", "age" : 30 } # 刪除匹配到的文檔對象中的多條記錄,可以發現name為angina的所有文檔記錄都沒有了 > db.userinfo.deleteMany({'name':"angina"}) { "acknowledged" : true, "deletedCount" : 5 } > db.userinfo.find() { "_id" : ObjectId("5a5c5fb18c6f3bc41b4589b4"), "hobbies" : [ "tea", "singing" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b5"), "hobbies" : [ "music", "read", "dancing", "tea" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b6"), "hobbies" : [ "tea" ] } { "_id" : ObjectId("5a5c60028c6f3bc41b4589b7"), "name" : "carson666", "is_sb" : false, "hobbies" : [ "music", "read", "dancing" ] } # 刪除集合中的所有文檔對象,相當於關系型數據庫中的表操作:truncate emp; > db.userinfo.deleteMany({}) { "acknowledged" : true, "deletedCount" : 4 } > db.userinfo.find() >

排序顯示:

> db.users.find() { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "name" : "carson666" } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "alex" } { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "carson" } { "_id" : ObjectId("5a5c854e8c6f3bc41b4589c1"), "name" : "angina", "age" : 40 } { "_id" : ObjectId("5a5c856d8c6f3bc41b4589c2"), "name" : "tom" } # 按照name升序顯示 > db.users.find().sort({"name":1}) { "_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "alex" } { "_id" : ObjectId("5a5c854e8c6f3bc41b4589c1"), "name" : "angina", "age" : 40 } { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "carson" } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "name" : "carson666" } { "_id" : ObjectId("5a5c856d8c6f3bc41b4589c2"), "name" : "tom" } # 按照name降序顯示 > db.users.find().sort({"name":-1}) { "_id" : ObjectId("5a5c856d8c6f3bc41b4589c2"), "name" : "tom" } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "name" : "carson666" } { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "carson" } { "_id" : ObjectId("5a5c854e8c6f3bc41b4589c1"), "name" : "angina", "age" : 40 } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "alex" }

分頁顯示

# 分頁:--limit代表取多少個document,skip代表跳過前多少個document。 按照name進行升序排列 > db.users.find().sort({"name":1}) { "_id" : ObjectId("5a5c83c48c6f3bc41b4589bf"), "name" : "alex" } { "_id" : ObjectId("5a5c854e8c6f3bc41b4589c1"), "name" : "angina", "age" : 40 } { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "carson" } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "name" : "carson666" } { "_id" : ObjectId("5a5c856d8c6f3bc41b4589c2"), "name" : "tom" } 現在我們使用分頁顯示,首先是按照name升序排列,然后跳過前面2個文檔對象,接着取出3個文檔對象 > db.users.find().sort({'name':1}).limit(3).skip(2) { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "carson" } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "name" : "carson666" } { "_id" : ObjectId("5a5c856d8c6f3bc41b4589c2"), "name" : "tom" } 我們來看看使用下面的表達式會怎么樣: > db.users.find().sort({'name':1}).skip(2).limit(3) { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "carson" } { "_id" : ObjectId("5a5c83c48c6f3bc41b4589be"), "name" : "carson666" } { "_id" : ObjectId("5a5c856d8c6f3bc41b4589c2"), "name" : "tom" } 結果和上面一樣的,最后來看看下面的: 跳過排好序的文檔對象中的2個,接着取一個出來 > db.users.find().sort({'name':1}).limit(1).skip(2) { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "carson" } > db.users.find().sort({'name':1}).skip(2).limit(1) { "_id" : ObjectId("5a5c83c58c6f3bc41b4589c0"), "name" : "carson" }

獲取數量:調用count()方法

# 查詢名字以c開頭的文檔對象的個數 > db.users.count({'name':/^c.*?/i}) 2
> db.users.find({'name':/^c.*?/i}).count() 2

Null值的匹配:

db.t2.insert({'a':10,'b':111}) db.t2.insert({'a':20}) db.t2.insert({'b':null}) db.t2.insert({'c':110, 'b':112, 'd':null}) db.t2.insert({'e': 12}) db.t2.insert({'spark': 666,'carson':999}) > db.t2.find() { "_id" : ObjectId("5a5da18cbb7aac032e104be1"), "a" : 10, "b" : 111 } { "_id" : ObjectId("5a5da18cbb7aac032e104be2"), "a" : 20 } { "_id" : ObjectId("5a5da18cbb7aac032e104be3"), "b" : null } { "_id" : ObjectId("5a5da1f1bb7aac032e104be4"), "c" : 110, "b" : 112, "d" : null } { "_id" : ObjectId("5a5da1f2bb7aac032e104be5"), "e" : 12 } { "_id" : ObjectId("5a5da248bb7aac032e104be6"), "spark" : 666, "carson" : 999 } """ 從結果可以看出來,{'key':null} 表示匹配key的值為null或者沒有這個key,可以看到匹配的文檔對象中 要么沒有b這個key,例如 "a" : 20和"e" : 12"spark" : 666, "carson" : 999, 要么b這個key的值就是null """ > db.t2.find({'b':null}) { "_id" : ObjectId("5a5da18cbb7aac032e104be2"), "a" : 20 } { "_id" : ObjectId("5a5da18cbb7aac032e104be3"), "b" : null } { "_id" : ObjectId("5a5da1f2bb7aac032e104be5"), "e" : 12 } { "_id" : ObjectId("5a5da248bb7aac032e104be6"), "spark" : 666, "carson" : 999 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM