MongoDB Shell 命令實(shí)例總結(jié)【進(jìn)階篇】
本文實(shí)例講述了MongoDB Shell 命令。分享給大家供大家參考,具體如下:
原始文件請(qǐng)到我的github上去下載:https://github.com/yangqingxian/mongodb
這里先講幾件事:
1、這是第三次修改這篇文章了,也是第一次正真意義上的使用 github 來(lái)控制版本,想想還是有點(diǎn)小激動(dòng)的:)
2、其中的內(nèi)容結(jié)構(gòu)與 mongodb基礎(chǔ)命令是一致的,只不過(guò)添加了很多內(nèi)容進(jìn)去,適用于想進(jìn)一步學(xué)習(xí)mongodb數(shù)據(jù)庫(kù)的人
3、我其實(shí)也是菜鳥(niǎo),所以我會(huì)用很白目的語(yǔ)言來(lái)解釋其中的內(nèi)容,如果你也跟我一樣,那就兩只鳥(niǎo)一起飛吧
4、接下來(lái)的內(nèi)容均是我對(duì)《MongoDB大數(shù)據(jù)權(quán)威指南(第2版)》的摘記
5、其中的命令例子并沒(méi)有事先創(chuàng)建好數(shù)據(jù)庫(kù)、集合,都是要用到的時(shí)候臨時(shí)寫的,注意理解
mongodb數(shù)據(jù)庫(kù)結(jié)構(gòu)與傳統(tǒng)關(guān)系型數(shù)據(jù)庫(kù)的比較,便于理解接下來(lái)的內(nèi)容
數(shù)據(jù)庫(kù)->集合->文檔
數(shù)據(jù)庫(kù)->表 ->列
--------------------數(shù)據(jù)庫(kù)內(nèi)容------------------
查看所有數(shù)據(jù)庫(kù)
show dbs
刪除數(shù)據(jù)庫(kù)
db.dropDatebase()
--------------------集合內(nèi)容--------------------
創(chuàng)建集合
db.createCollection()
查看所有集合\表
show collections show tables
選定某一集合
use db_name
查看集合的信息
db.stats()
刪除一個(gè)集合,但是需要先指定一個(gè)數(shù)據(jù)庫(kù),即先執(zhí)行 use db_name
db.dropDatabase()
修改集合的名稱
db.collection_name.renameCollection('new_name')
----------------------文檔內(nèi)容---------------------
插入數(shù)據(jù)
db.collection_name.insert(document) db.collection_name.save(document)
查詢數(shù)據(jù)多條數(shù)據(jù)
db.collection_name.find()
1、可以指定返回的內(nèi)容
參數(shù)解釋
db.collection_name.find( {query_term:value}, return_key_name:1} )
a find()函數(shù)的第一個(gè)參數(shù)是查詢條件,即匹配該內(nèi)容的文檔都會(huì)被篩選出來(lái),如果沒(méi)有查詢條件,則輸入{},不可以為空
b find()函數(shù)的第二個(gè)參數(shù)是指定返回的內(nèi)容,例如一個(gè)student的集合中的一個(gè)xiaoming文檔中包含多條內(nèi)容,姓名、學(xué)生號(hào)、家庭住址等,現(xiàn)在我只想看姓名,不想查詢的時(shí)候返回xiaoming文檔的全部?jī)?nèi)容,就可以使用這種'鍵名:1'的形式,后面的1表示篩選出該內(nèi)容并正序輸出,0表示篩選出除了該內(nèi)容的其余部分,-1表示逆序跟1一樣的結(jié)果
c 可以返回多條記錄,這里只是舉個(gè)例子,還是拿ixaoming的例子
{ 'name':1, 'student_id':1 }
這樣就返回了兩個(gè)信息,一個(gè)name,一個(gè)student_id
2、查詢嵌套信息
結(jié)合二維數(shù)組理解下面的這個(gè)信息
{ 'name':'yang', 'sex':'man', 'skill':[ {'php':1}, {'mongodb':4}, {'redis':5} ], 'favorite_food':'meat' }
其中如果使用skill來(lái)作為find()的查詢條件的話,千萬(wàn)別寫成這樣
---錯(cuò)誤例子---
db.self.find({'skill':[{'php':1}]})
這樣是查不到的,因?yàn)檫@樣mongodb會(huì)將{'skill':[{'php':1}]}解析成skill數(shù)組下只包含'php':1這一條記錄的內(nèi)容,上面的例子明顯不符合這一要求,所以查詢不到
---正確的例子---
db.self.find({'skill.php':1})
這里使用了 . 告訴mongodb數(shù)據(jù)庫(kù)去匹配skill數(shù)組下php為1的內(nèi)容,重點(diǎn)在于skill下是否有'php':1這一條記錄
---正確例子2---
如果一定要使用上面的錯(cuò)誤例子的方式查詢數(shù)據(jù),可以使用$elemMatch參數(shù),注意該參數(shù)使用的位置
db.self.find({ 'skill':{$elemMatch: {'php':1} } })
這里的$elemMatch是作為條件操作符來(lái)使用的
查詢單條數(shù)據(jù)
db.collection_name.findOne()
skip 跳過(guò)查詢的最開(kāi)始的數(shù)量,limit,限制返回?cái)?shù)量,sort,當(dāng) x:1 表示正序,x:-1 表示逆序
db.collection_name.find().skip(Number).limit(Number).sort({x:1})
計(jì)算符合查詢條件的文檔的數(shù)量
db.collection_name.find().count()
count()函數(shù)默認(rèn)情況下會(huì)忽略skip()或limit()函數(shù),例如假設(shè)student集合中有4個(gè)文檔,下面的三條語(yǔ)句將顯示不同的結(jié)果
db.student.find().limit(1).count()
結(jié)果為4,count忽略了limit(1)的條件
db.student.find().limit(1).count(true)
結(jié)果為1,為count()傳入?yún)?shù)true
獲取結(jié)果的唯一值
db.collection_name.distinct('key_name')
也是查詢的函數(shù),只不過(guò)他比起find()會(huì)將查詢結(jié)果顯示唯一值,而不是根據(jù)原有集合中,文檔的數(shù)量來(lái)顯示結(jié)果,結(jié)合關(guān)系型數(shù)據(jù)庫(kù)中的distinct來(lái)理解,舉個(gè)例子,有一個(gè)圖書集合--books,該集合下有書名,作者,出版日期等信息,注意,一個(gè)作者可能寫了很多本書,現(xiàn)在我想查看在該集合中有多少作者,如果我直接使用上面的find()函數(shù)來(lái)搜索的話
db.books.find( {}, {'writer':1} )
這樣會(huì)將全部的作者列出來(lái),但是很多都是重復(fù)的,因?yàn)閒ind()是根據(jù)文檔數(shù)量來(lái)返回結(jié)果的,而distinct()會(huì)將結(jié)果篩選,
其中重復(fù)的部分
db.books.distinct('writer')
將查詢結(jié)果分組
db.collection_name.group()
- 參數(shù)1 key 按照此key進(jìn)行分組
- 參數(shù)2 initial 設(shè)置變量,該變量會(huì)在最終輸出,注意,這個(gè)變量是對(duì)每個(gè)分組都會(huì)定義一個(gè)的,一個(gè)新的分組開(kāi)始就重新創(chuàng)建
- 參數(shù)3 reduce 一個(gè)函數(shù),在文檔分組期間執(zhí)行,即對(duì)一個(gè)文檔進(jìn)行一次分組就會(huì)執(zhí)行一次,傳入兩個(gè)參數(shù),一個(gè)是代表initial的參數(shù),一個(gè)是目前進(jìn)行分組的文檔,為了便于理解,分別取名叫out和doc
- 參數(shù)4 keyf,可選,作用跟key一樣,但是可以指定一個(gè)函數(shù)創(chuàng)建一個(gè)原本不存在于文檔中的字段作為分組的依據(jù),需要傳入一個(gè)當(dāng)前文檔的參數(shù)
- 參數(shù)5 cond 過(guò)濾條件,只有滿足該條件的文檔才能參與分組
- 參數(shù)6 finalize 在分組完成后執(zhí)行的函數(shù),傳入代表initial的參數(shù)
下面來(lái)看一個(gè)例子就能大致上了解了,先傳入幾個(gè)文檔到orders集合中
data1={ "_id" : ObjectId("552a330e05c27486b9b9b650"), "_class" : "com.mongo.model.Orders", "onumber" : "002", "date" : ISODate("2014-01-03T16:03:00Z"), "cname" : "zcy", "item" : { "quantity" : 1, "price" : 4.0, "pnumber" : "p002" } } data2={ "_id" : ObjectId("552a331d05c275d8590a550d"), "_class" : "com.mongo.model.Orders", "onumber" : "003", "date" : ISODate("2014-01-04T16:03:00Z"), "cname" : "zcy", "item" : { "quantity" : 10, "price" : 2.0, "pnumber" : "p001" } } data3={ "_id" : ObjectId("552a333105c2f28194045a72"), "_class" : "com.mongo.model.Orders", "onumber" : "003", "date" : ISODate("2014-01-04T16:03:00Z"), "cname" : "zcy", "item" : { "quantity" : 30, "price" : 4.0, "pnumber" : "p002" } } data4={ "_id" : ObjectId("552a333f05c2b62c01cff50e"), "_class" : "com.mongo.model.Orders", "onumber" : "004", "date" : ISODate("2014-01-05T16:03:00Z"), "cname" : "zcy", "item" : { "quantity" : 5, "price" : 4.0, "pnumber" : "p002" } } db.orders.insert(data1) db.orders.insert(data2) db.orders.insert(data3) db.orders.insert(data4)
接下來(lái)展示group()
函數(shù)
例1
db.orders.group({ key:{data:1,'item.pnumber':1}, initial:{'total':0}, reduce:function (doc,out){ out.total+=doc.item.quantity } })
首先是按照data和ietm數(shù)組中的pnumber分組
接著定義了輸出變量total,記錄每個(gè)產(chǎn)品的總數(shù)
接著是定義處理函數(shù),也就是reduce中的函數(shù),注意,傳入?yún)?shù)的先后順序,第一個(gè)參數(shù)表示當(dāng)前進(jìn)行分組的文檔,第二個(gè)參數(shù)表示initial,所以doc能直接調(diào)用doc.item.quantity,即文檔的內(nèi)容,out能調(diào)用out.total,即initial的內(nèi)容
例2
db.orders.group({ keyf:function(doc){ return {'month':doc.date.getMonth()+1}; }, initial:{'total':0,'money':0}, reduce:function (doc,out){ out.total+=doc.item.quantity*doc.item.price }, finalize:function (out){ out.avg=out.money/out.total; return out; } })
首先,這個(gè)例子展示了keyf的用法,他返回了一個(gè)新的字段--month,接下來(lái)mongodb會(huì)按照month的計(jì)算結(jié)果分類
接著,就是在keyf以及finalize的函數(shù)中都有傳入?yún)?shù),其實(shí)這個(gè)參數(shù)跟reduce中的參數(shù)名字沒(méi)有關(guān)系,這里寫在一起主要是為了便于理解其含義
最后就是在finalize中臨時(shí)創(chuàng)建了一個(gè)變量avg,這個(gè)avg在最后也是會(huì)被輸出的
最后一點(diǎn),在函數(shù)中處理結(jié)果都是會(huì)被return的
----------------使用條件操作符來(lái)篩選查詢結(jié)果------------------
一般情況下都使用在find()的第一個(gè)參數(shù)內(nèi)部,作為篩選條件使用
---$gt,$lt,$get,$lte,$ne---
db.collection_name.find( { key_name:{$gt:value} })
注意操作符的位置,看例子可以便于理解
db.student.find( { 'height':{$gt:180} })
表示篩選出學(xué)生集合中身高高于180的學(xué)生
可以同時(shí)使用兩個(gè)操作符來(lái)指定范圍
db.student.find({ 'height':{$gt:180,$lt:220} })
這兩個(gè)的使用方法跟上面是一樣的,但是需要單獨(dú)拎出來(lái)講,因?yàn)橛悬c(diǎn)特殊
---$in,$nin---
db.student.find({ 'height':{$in:[170,180,190,200]} })
表示篩選出身高為170,180,190,200的學(xué)生,$nin就是篩選除了170,180,190,200之外的學(xué)生
---$all---
上面的$in中的內(nèi)容是‘或'的形式,只要你的身高是170,或180,或190,或200,那么你就符合篩選條件,而$all則是且的關(guān)系
db.student.find({ 'height':{$all:[170,180,190,200]} })
這句話的意思是你的身高既是170,又是180,又是190,又是200才能滿足條件
---$or---
db.student.find({ $or:[ {'score':100}, {'sex':man} ] })
上面的例子中,score:100與sex:man是‘或'的關(guān)系,結(jié)合下面的例子就可以看出$or的作用了
db.student.find( {'score':100,'sex':'man'} )
其中的score:100與sex:man是且的關(guān)系
limit(x)
函數(shù)加skip(y)
函數(shù)=$slice:[y,x]
具體使用方法可以看下面這個(gè)例子
db.student.find( {}, {'height':{$slice:[10,5]}} )
還是那句老話,注意$slice的位置,這句話表示篩選身高第11到15的人,第一個(gè)參數(shù)是skip()的參數(shù),第二個(gè)是limit()
limit()
函數(shù)是限制返回文檔的數(shù)量的,$size是篩選符合數(shù)量的數(shù)組的,看下面的例子就明白了
先在數(shù)據(jù)庫(kù)中添加以下信息
message={ 'cds':[ {'first_song':'hello'}, {'second_song':'world'}, {'third_song':'again'} ] } db.songs.insert(message)
接著我們來(lái)查詢一下上述結(jié)果
db.songs.find( {'cds':{$size:2}} )
無(wú)返回結(jié)果,因?yàn)閏ds數(shù)組里有3組數(shù)據(jù)
db.songs.find( {'cds':{$size:3}} )
返回全部結(jié)果,注意一點(diǎn),這里是作為find()函數(shù)的第一個(gè)參數(shù)傳入的,所以是篩選條件
篩選含有特定字段的值
db.collection_name.find( { key_name:{$exit:true} })
返回存在該字段的文檔,注意,這里是存在該字段,而沒(méi)有指定該字段的具體內(nèi)容
根據(jù)數(shù)據(jù)類型篩選返回結(jié)果
db.collection_name.find( { 'key_name':{$type:x} })
其中的x取值內(nèi)容有很多,這里就不介紹了,因?yàn)樘嗔丝匆槐橐矝](méi)用
在篩選中使用正則表達(dá)式
db.collection_name.find( { 'key_name':/ / })
在/ /中添加正則表達(dá)式的內(nèi)容
更新數(shù)據(jù)
db.collection_name.update({original_key:original_value},{new_key:new_value})
1、只要原 collection 中包含 original_key:original_value 就會(huì)被選中成為操作對(duì)象
2、整個(gè) collection 都會(huì)被更新成 new_key:new_value ,而不單單就只是更新 original_key:original_value
相較于上面會(huì)更新整個(gè)集合,下面添加了 $set: 的形式來(lái)只進(jìn)行部分字段的更新
db.collection_name.update({original_key:original_value},{$set:{new_key:new_value}})
上面使用$set更新了一條字段,可以使用$unset刪除一條字段
db.collection_name.update{ {}, {$unset:{key:value}} }
如果此更新數(shù)據(jù)不存在就創(chuàng)建這一條數(shù)據(jù),加第三個(gè)參數(shù)為 true 就可以實(shí)現(xiàn)了
db.collection_name.update({original_key:original_value},{new_key:new_value},true)
或者下面的形式也可以
db.collection_name.update({original_key:original_value},{new_key:new_value},{upsert:true})
update 只會(huì)更新第一條滿足條件的記錄,但是想更新多條記錄時(shí),將第三個(gè)參數(shù)設(shè)置為 false,第四個(gè)參數(shù)設(shè)置為 true,而且還要設(shè)置 $set
db.collection_name.update({original_key:original_value},{$set{new_key:new_value}},false,true)
------------------插入數(shù)據(jù)——數(shù)組部分--------------------
插入數(shù)據(jù)
db.collection_name.update( {original_key:value}, {$push:{ new_key:new:value }} )
注意,如果original_key不存在,則會(huì)被創(chuàng)建,并且定義為數(shù)組的形式,new_key:value則是第一個(gè)值
如果original_key存在,并且數(shù)數(shù)組,則插入new_key:value,如果不是數(shù)組,則報(bào)錯(cuò)
一次性插入多個(gè)值,前面是使用$push一次插入一個(gè)值,如果想插入多個(gè)值的話,需要使用下面的內(nèi)容
db.collection_name.update( {original_key:value}, {$push:{ new_key:{ $each:[ 'value1', 'value2', 'value3' ] } } })
注意這里的$push是針對(duì)數(shù)組操作的,也就是$each后面的內(nèi)容都將添加到new_key的數(shù)組中
與$push對(duì)應(yīng),$pop刪除數(shù)組中的數(shù)據(jù)
db.collection_name.update( {original_key:value}, {$pop:{ {original_key:1} } })
注意,這里的1表示刪除的數(shù)量,可以是2,3等整數(shù),表示從數(shù)組的后端開(kāi)始刪除,也可以是-1等負(fù)數(shù),表示從數(shù)組的前端開(kāi)始刪除
前面的$pop可以指定刪除的數(shù)量,但是不能指定刪除的條件,$pull則可以
db.collection_name.update( {original_key:value}, {$pull: {key1:value1} } )
$pull會(huì)刪除掉key1中所有value1的數(shù)據(jù),注意,是刪除key1中的value1數(shù)據(jù),不是刪除key1,所以只要key1數(shù)組中包含了value1就會(huì)被刪除掉value1
與$pull類似,$pullAll可以刪除掉多個(gè)數(shù)據(jù)
db.collection_name.update( {original_key:value}, {$pullAll:{ key1: [ 'value1', 'value2', 'value3' ] } })
$addToSet是一個(gè)非常實(shí)用的向數(shù)組添加數(shù)據(jù)的命令,如果該數(shù)據(jù)不存在則添加,存在就不會(huì)重復(fù)添加了
db.collection_name.update( {original_key:value}, {$addToSet:{ new_key:{ $each:[ 'value1', 'value2', 'value3' ] } } })
設(shè)想一下,如果這里不添加$each的情況,如果不添加$each,則會(huì)變成往數(shù)組new_key中直接添加新的數(shù)組
['value1','value2','value3']
可以嘗試一下,理解$each的功能,回到$addToSet上來(lái),如果原數(shù)組中就存在value1,value2,value3則不會(huì)添加,如果不存在,則將沒(méi)有的添加進(jìn)去,有的也不會(huì)重復(fù)添加,彼此之間不是互相影響的。
原子操作
這里就不解釋什么叫原子操作了,對(duì)于我們使用者來(lái)說(shuō)只要知道怎么采用原子操作就可以了
db.collection_name.findAndModify( { query:{key:value}, sort:{key2:1/-1}, update/remove:true, new:true } )
query 指定查詢的文檔
sort 排序,1,-1的含義這里就不解釋了,跟上面一樣
update/remove 表示操作
new 表示返回最終的修改結(jié)果,可以不填
刪除所有查找到的數(shù)據(jù)
db.coolection_name.remove({key:value})
刪除一張表
db.collection_name.drop()
查看集合的索引
db.collection_name.getIndexes()
創(chuàng)建索引
db.collection_name.ensureIndex({key:value})
前面是根據(jù)key:value
的形式創(chuàng)建索引的,接下來(lái)就為一集合的某一字段全部創(chuàng)建索引
db.collection_name.ensureIndex({key:1})
復(fù)合索引的創(chuàng)建就是在其中多添加幾個(gè)內(nèi)容
刪除索引
db.collection_name.dropIndex({key:value})
刪除所有索引
db.collection_name.dropIndexes()
前面我們操作的都是一個(gè)集合,接下來(lái)我們要學(xué)習(xí)簡(jiǎn)單的操作多個(gè)集合了,有兩種方式,手動(dòng)或者使用DBRef
先創(chuàng)建兩個(gè)集合
collection1={ 'name':'yang', 'sex':'man' } collection2={ 'id':1, 'name':'yang', 'math':60, 'pe':30, 'chinese':60 } db.student.save(collection2) db.yang.save(collection)
接下來(lái)就是大致思路了
yang=db.yang.findOne() db.student.find( {'name':yang.name} )
mongodb不支持像傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)那樣的多表操作,mongodb都是需要先將數(shù)據(jù)保存好,再來(lái)調(diào)用的,如上面的yang保存的就是find()查詢所需要的內(nèi)容,需要先將數(shù)據(jù)從數(shù)據(jù)庫(kù)中讀出保存好再來(lái)調(diào)用,其中yang.name就等于'yang'
接下來(lái)就是使用DBRef引用數(shù)據(jù)庫(kù)了,調(diào)用DBRef需要傳入三個(gè)參數(shù),第一個(gè)調(diào)用的collection_name,id,db_name,這個(gè)可選,還是上面的這個(gè)例子,接下來(lái)使用DBRef的方式,這玩意我搞不定
希望本文所述對(duì)大家MongoDB數(shù)據(jù)庫(kù)程序設(shè)計(jì)有所幫助。
相關(guān)文章
MongoDB數(shù)據(jù)庫(kù)的日志文件深入分析
這篇文章主要給大家介紹了關(guān)于MongoDB數(shù)據(jù)庫(kù)日志的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用MongoDB具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09Windows或Linux系統(tǒng)中備份和恢復(fù)MongoDB數(shù)據(jù)的教程
不得不說(shuō)MongoDB的備份回復(fù)操作對(duì)比其他數(shù)據(jù)庫(kù)來(lái)說(shuō)真的算得上是簡(jiǎn)便的,無(wú)論是在Windows的命令行中或者是Linux里的腳本執(zhí)行,這里我們就來(lái)看一下Windows或Linux系統(tǒng)中備份和恢復(fù)MongoDB數(shù)據(jù)的教程2016-06-06MongoDB數(shù)據(jù)庫(kù)類replace替換字符串指定內(nèi)容
mongoDB是沒(méi)有定義replace函數(shù)的,那么如果有需求需要替換nongo中數(shù)據(jù)的某一部分,怎么辦?下面這篇文章主要給大家介紹了關(guān)于MongoDB數(shù)據(jù)庫(kù)類replace替換字符串指定內(nèi)容的相關(guān)資料,需要的朋友可以參考下2023-05-05Centos 7下Mongodb開(kāi)機(jī)無(wú)法自啟動(dòng)的解決方法
這篇文章主要介紹了Centos 7下Mongodb開(kāi)機(jī)無(wú)法自啟動(dòng)的解決方法,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-03-03MongoDB 導(dǎo)出導(dǎo)入備份恢復(fù)數(shù)據(jù)詳解及實(shí)例
這篇文章主要介紹了MongoDB 導(dǎo)出導(dǎo)入備份恢復(fù)數(shù)據(jù)詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2016-10-10Mongodb實(shí)現(xiàn)定時(shí)備份與恢復(fù)的方法教程
這篇文章主要給大家介紹了Mongodb實(shí)現(xiàn)定時(shí)備份與恢復(fù)的方法教程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來(lái)學(xué)習(xí)學(xué)習(xí)吧。2017-06-06