MongoDB使用總結(jié)

MongoDB使用總結(jié)

數(shù)據(jù)庫操作

  • show dbs : 顯示所有的數(shù)據(jù)庫
  • use user : 選擇數(shù)據(jù)庫user病毡,如果這個數(shù)據(jù)庫存在,那么就使用,不存在就新建恭垦,但是此時的數(shù)據(jù)庫中根本不存在數(shù)據(jù),因此使用show dbs不能顯示該數(shù)據(jù)庫
  • db.dropDatabase() : 刪除數(shù)據(jù)庫格嗅,其中的db表示當(dāng)前數(shù)據(jù)庫

集合操作(表)

  • 在MongoDB中番挺,數(shù)據(jù)庫中的集合相當(dāng)于SQL中的表,一個數(shù)據(jù)庫中可以存在多個集合屯掖,每一個集合都是一個JSON文檔形式的存儲
  • show tables : 顯示所有的集合
  • show collections : 顯示所有的集合

創(chuàng)建集合

  • db.createCollection(name, options)
  • 文檔

刪除集合

  • db.collection.drop()
    • db.user.drop() : 刪除user集合

文檔操作

  • 一個集合中可以包含多條文檔玄柏,一個文檔就相當(dāng)于SQL中的一條數(shù)據(jù),這里的文檔是JSON格式的文檔

插入文檔

  • db.collectionName.insert(JSON)

    • db.user.insert({name:"陳加兵",age:22}) : 向user集合中插入一條文檔贴铜,如果這個user集合不存在粪摘,那么就會新建一個,這個方法默認(rèn)會為我們插入一個_id

更新文檔

update() 方法用于更新已存在的文檔绍坝。語法格式如下:

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

參數(shù)說明:

  • query : update的查詢條件徘意,類似sql update查詢內(nèi)where后面的。
  • update : update的對象和一些更新的操作符(如,?inc...)等轩褐,也可以理解為sql update查詢內(nèi)set后面的
  • upsert : 可選映砖,這個參數(shù)的意思是,如果不存在update的記錄灾挨,是否插入objNew,true為插入邑退,默認(rèn)是false,不插入劳澄。
  • multi : 可選地技,mongodb 默認(rèn)是false,只更新找到的第一條記錄,如果這個參數(shù)為true,就把按條件查出來多條記錄全部更新秒拔。
  • writeConcern :可選莫矗,拋出異常的級別。

實例

  • db.user.update({name:"jack"},{$set:{name:"tom"}}) :相當(dāng)于sql語句中的update user set name="tom" where name="jack",不過這里默認(rèn)只是更新一條
  • db.user.update({name:"陳加兵"},{$set:{name:"鄭元梅"}},{multi:true}) : 更新所有的數(shù)據(jù)
  • db.user.update({name:"陳加兵"},{$set:{name:"鄭元梅"}},{upsert:true}) : 更新數(shù)據(jù)砂缩,如果不存在就插入
  • 這里的query條件也是可以使用邏輯比較的作谚,比如age>12,后續(xù)在講到查詢文檔的時候會詳細(xì)描述

刪除文檔

  • 刪除格式庵芭,默認(rèn)是刪除多條妹懒,但是我們可以設(shè)置justone : true或者justone:1即可刪除一條數(shù)據(jù)
db.collection.remove(
   <query>,
   {
     justOne: <boolean>,
     writeConcern: <document>
   }
)
  • db.user.remove({name:"陳加兵"}) : 刪除全部name=陳加兵的文檔
  • db.user.remove({}) : 刪除集合user中的全部文檔
  • db.user.remove({}) : 刪除全部文檔,因為這里沒有條件
  • db.user.remove({name:"陳加兵"},{justone:true}) : 只刪除一條文檔

查詢文檔

  • db.collection.findOne(query,projection) : 只顯示滿足條件的一條文檔

  • 格式:db.collection.find(query,projection) : 查詢滿足條件的全部文檔

    • query :可選双吆, 查詢的條件眨唬,相當(dāng)于where子句
    • projection: 可選会前,使用投影操作符指定返回的鍵。查詢時返回文檔中所有鍵值匾竿, 只需省略該參數(shù)即可(默認(rèn)省略)

插入數(shù)據(jù)(準(zhǔn)備)

db.user.insert({name:"Jack",age:22})
db.user.insert({name:"Tom",age:40})
db.user.insert({name:"Mary",age:25})
db.user.insert({name:"Lucy",age:22})

查詢?nèi)?/h4>
  • db.user.find().pretty() : 這里沒有指定查詢條件瓦宜,那么就是查詢?nèi)?/li>

指定顯示字段

  • 默認(rèn)顯示全部的字段,但是我們可以指定projection來顯示指定的字段
  • inclusion模式岭妖,指定返回的鍵临庇,比如db.user.find({},{name:1}),這里只會顯示_idname這兩個字段,其他的字段都是不會顯示的
  • exclusion模式昵慌,指定不反回的鍵假夺,比如db.user.find({},{name:0}) : 這里只會顯示age_id,只有name不顯示
  • 兩種模式不可以混用,比如db.user.find({},{name:1,age:0}) ,這個是不可以的

指定查詢條件

  • db.user.find({name:"Jack"}) : 查詢name=Jack的全部文檔內(nèi)容
  • db.user.find({name:"Jack"},{name:0}) : 不顯示name字段

AND條件

  • db.user.find({name:"Jack",age:22}) : 查詢name=Jack并且age=22的文檔信息
  • db.user.find({$and:[{expression1},{expression2},{experssion3},......]})
    • db.user.find({$and:[{name:"Jack"},{age:22}]}) : 和上面一樣的效果

OR 條件

  • db.user.find({$or:[{expression1},{expression2},{expression3}......]})
    • db.user.find({$or:[{name:"Jack"},{age:25}]}) : 查找name=Jack或者age=25的文檔信息

AND 和 OR 聯(lián)合使用

  • db.user.find({name:"Jack",$or:[{_id:1},{age:22}]}) : 查找name=Jack and (_id=1 or age=22)

條件操作符

  • (>) 大于 - $gt
  • (<) 小于 - $lt
  • (>=) 大于等于 - $gte
  • (<= ) 小于等于 - $lte
  • (!=) 不等于 - $ne
實例
  • db.user.find({age:{$gt:22}}) : 查找 age>22的信息
  • db.user.find({age:{$gte:22},name:"Jack"}) : 查找age>=22 and name=Jack的信息

limit

  • 指定顯示記錄的條數(shù)
  • db.user.find().limit(2) : 只顯示兩條記錄
  • db.user.find({name:"Jack"}).limit(2)

skip

  • 跳過的條數(shù)
  • db.user.find().skip(10) : 跳過前面的十條記錄废离,顯示后面的

分頁查詢

  • 顯示第三頁侄泽,每頁顯示10條信息礁芦,相當(dāng)于SQL中的select * from user limit 20,5
    • db.user.find().skip(20).limit(5)

sort 排序

  • 在MongoDB中使用使用sort()方法對數(shù)據(jù)進行排序蜻韭,sort()方法可以通過參數(shù)指定排序的字段,并使用 1 和 -1 來指定排序的方式柿扣,其中1 為升序排列肖方,而-1是用于降序排列。
  • db.collection.find().sort({key:1})
  • db.user.find().sort({age:-1}) : 按照age降序排列
  • db.user.find({},{name:1,age:1}).sort({age:-1,name:1}) : 按照name升序未状,age降序排列

limit俯画,skip,sort執(zhí)行順序

  • 執(zhí)行順序為:sort() --- > skip() ----> limit() ,這個相當(dāng)于SQL中的select * from name where group by having order by limit m,n 這種順序一樣

$in

  • 表示一個數(shù)據(jù)在多個數(shù)據(jù)中司草,類似于SQL中的in
  • db.user.find({age:{$in:[22,33,44]}}) : 查找age in (22,33,44)之中的任意一個

$nin

  • 相當(dāng)于SQL中的not in
  • db.user.find({age:{$nin:[22,33,44]}})

$exists

  • 表示不存在
  • db.user.find({sex:{$exists:false}}) : 查找不存在sex這個字段的文檔

slice

$slice操作符控制查詢返回的數(shù)組中元素的個數(shù)艰垂。此操作符根據(jù)參數(shù){ field: value } 指定鍵名和鍵值選擇出文檔集合,并且該文檔集合中指定array鍵將返回從指定數(shù)量的元素埋虹。如果count的值大于數(shù)組中元素的數(shù)量猜憎,該查詢返回數(shù)組中的所有元素的。

語法:db.collection.find( { field: value }, { array: {$slice: count }});

  • 下面將查詢grades中的前兩個數(shù)
db.user.find({name:'jack'},{grades:{$slice:2},name:1,age:1,'school.name':1});

//輸出搔课,可以看出這里的grades只輸出了前面兩個

{ "_id" : ObjectId("59057c16f551d8c9003d31df"), "name" : "jack", "age" : 22, "grades" : [ 22, 33 ], "school" : { "name" : "shida" } }
  • 下面將輸出后3個數(shù)據(jù)
db.user.find({name:'jhon'},{grades:{$slice:-3},name:1});

//輸出
{ "_id" : ObjectId("59057c16f551d8c9003d31e0"), "name" : "jhon", "grades" : [ 22, 44, 88 ] }
  • 下面介紹指定一個數(shù)組作為參數(shù)胰柑。數(shù)組參數(shù)使用[ skip , limit ] 格式,其中第一個值表示在數(shù)組中跳過的項目數(shù),第二個值表示返回的項目數(shù)爬泥。
db.user.find({name:'jack'},{grades:{$slice:[2,2]},name:1});  //這里將會跳過前面的兩個柬讨,直接得到后面的兩個數(shù)據(jù)


//輸出

{ "_id" : ObjectId("59057c16f551d8c9003d31df"), "name" : "jack", "grades" : [ 44, 55 ] }

count

  • 統(tǒng)計數(shù)量
  • db.user.find().count() : 統(tǒng)計全部的數(shù)量
  • db.user.find({name:"Jack"}).count() : 統(tǒng)計name=Jack的人數(shù)

索引

  • db.collection.ensureIndex({key1:1}) : 創(chuàng)建索引,其中的key的值如果為1表示按照升序創(chuàng)建索引袍啡,-1表示降序創(chuàng)建索引

    • db.user.ensureIndex({name:1}) : 單個索引
    • db.user.ensureIndex({name:1,age:-1}) : 復(fù)合索引
  • ensureIndex() 接收可選參數(shù)踩官,可選參數(shù)列表如下:

Parameter Type Description
background Boolean 建索引過程會阻塞其它數(shù)據(jù)庫操作,background可指定以后臺方式創(chuàng)建索引境输,即增加 "background" 可選參數(shù)卖鲤。 "background" 默認(rèn)值為false肾扰。
unique Boolean 建立的索引是否唯一。指定為true創(chuàng)建唯一索引蛋逾。默認(rèn)值為false.
name string 索引的名稱集晚。如果未指定,MongoDB的通過連接索引的字段名和排序順序生成一個索引名稱区匣。
dropDups Boolean 在建立唯一索引時是否刪除重復(fù)記錄,指定 true 創(chuàng)建唯一索引偷拔。默認(rèn)值為 false.
sparse Boolean 對文檔中不存在的字段數(shù)據(jù)不啟用索引;這個參數(shù)需要特別注意亏钩,如果設(shè)置為true的話莲绰,在索引字段中不會查詢出不包含對應(yīng)字段的文檔.。默認(rèn)值為 false.
expireAfterSeconds integer 指定一個以秒為單位的數(shù)值姑丑,完成 TTL設(shè)定蛤签,設(shè)定集合的生存時間。
v index version 索引的版本號栅哀。默認(rèn)的索引版本取決于mongod創(chuàng)建索引時運行的版本震肮。
weights document 索引權(quán)重值,數(shù)值在 1 到 99,999 之間留拾,表示該索引相對于其他索引字段的得分權(quán)重戳晌。
default_language string 對于文本索引,該參數(shù)決定了停用詞及詞干和詞器的規(guī)則的列表痴柔。 默認(rèn)為英語
language_override string 對于文本索引沦偎,該參數(shù)指定了包含在文檔中的字段名,語言覆蓋默認(rèn)的language咳蔚,默認(rèn)值為 language.
  • db.user.ensureIndex({age:1},{background:true}) : 在后臺創(chuàng)建索引

聚合

  • 參考文章

  • db.collection.aggregate(pipeline,options)

    • db.user.aggregate([{$group:{_id:null,count:{$sum:1}}}]) : 查詢總數(shù)豪嚎,相當(dāng)于select count(*) from user,這里的聚合函數(shù)$sum表示求和,可以使用$引用集合中的字段谈火,也可以直接使用數(shù)字侈询,這里填寫1就表示查詢到一條記錄就加一,那么最后顯示的就是總數(shù)了堆巧。
      • _id : 表示需要分組的字段妄荔,如果為null表示不分組
    • db.user.aggregate([{$group:{_id:"$name",sum_age:{$sum:"$age"}}}]) : 根據(jù)字段name分組,對字段age求和,輸入如下
    { "_id" : "Mary", "sum_age" : 75 }
    { "_id" : "Jack", "sum_age" : 66 }
    { "_id" : "zhengyunamei", "sum_age" : 0 }
    { "_id" : "Tom", "sum_age" : 120 }
    { "_id" : "陳加兵", "sum_age" : 22 }
    { "_id" : "Lucy", "sum_age" : 66 }
    { "_id" : "鄭元梅", "sum_age" : 22 }
    
  • db.user.aggregate([{$group:{_id:null,max_age:{$max:"$age"}}}]) : 求出年齡最大的人信息
{ "_id" : null, "max_age" : 40 }

常用的聚合

表達(dá)式 描述 實例
$sum 計算總和谍肤。 db.mycol.aggregate([{group : {_id : "by_user", num_tutorial : {sum : "likes"}}}])
$avg 計算平均值 db.mycol.aggregate([{group : {_id : "by_user", num_tutorial : {avg : "likes"}}}])
$min 獲取集合中所有文檔對應(yīng)值得最小值啦租。 db.mycol.aggregate([{group : {_id : "by_user", num_tutorial : {min : "likes"}}}])
$max 獲取集合中所有文檔對應(yīng)值得最大值。 db.mycol.aggregate([{group : {_id : "by_user", num_tutorial : {max : "likes"}}}])
$push 在結(jié)果文檔中插入值到一個數(shù)組中荒揣。 db.mycol.aggregate([{group : {_id : "by_user", url : {push: "url"}}}])
$addToSet 在結(jié)果文檔中插入值到一個數(shù)組中,但不創(chuàng)建副本系任。 db.mycol.aggregate([{group : {_id : "by_user", url : {addToSet : "url"}}}])
$first 根據(jù)資源文檔的排序獲取第一個文檔數(shù)據(jù)恳蹲。 db.mycol.aggregate([{group : {_id : "by_user", first_url : {first : "url"}}}])
$last 根據(jù)資源文檔的排序獲取最后一個文檔數(shù)據(jù) db.mycol.aggregate([{group : {_id : "by_user", last_url : {last : "url"}}}])

管道

管道在Unix和Linux中一般用于將當(dāng)前命令的輸出結(jié)果作為下一個命令的參數(shù)虐块。

MongoDB的聚合管道將MongoDB文檔在一個管道處理完畢后將結(jié)果傳遞給下一個管道處理。管道操作是可以重復(fù)的嘉蕾。

表達(dá)式:處理輸入文檔并輸出贺奠。表達(dá)式是無狀態(tài)的,只能用于計算當(dāng)前聚合管道的文檔错忱,不能處理其它的文檔儡率。

這里我們介紹一下聚合框架中常用的幾個操作:

  • $project:修改輸入文檔的結(jié)構(gòu)∫郧澹可以用來重命名儿普、增加或刪除域,也可以用于創(chuàng)建計算結(jié)果以及嵌套文檔掷倔。
  • $match:用于過濾數(shù)據(jù)眉孩,只輸出符合條件的文檔。$match使用MongoDB的標(biāo)準(zhǔn)查詢操作勒葱。
  • $limit:用來限制MongoDB聚合管道返回的文檔數(shù)浪汪。
  • $skip:在聚合管道中跳過指定數(shù)量的文檔,并返回余下的文檔错森。
  • $unwind:將文檔中的某一個數(shù)組類型字段拆分成多條吟宦,每條包含數(shù)組中的一個值篮洁。
  • $group:將集合中的文檔分組涩维,可用于統(tǒng)計結(jié)果。
  • $sort:將輸入文檔排序后輸出袁波。
  • $geoNear:輸出接近某一地理位置的有序文檔瓦阐。

$math

  • 這個相當(dāng)于where語句,用來過濾文檔的
  • **這個位置是非常重要的篷牌,如果在$group之前就是where子句睡蟋,如果在之后,那么相當(dāng)于having子句**
  • db.user.aggregate([{$match:{name:"Jack"}},{$group:{_id:null,count:{$sum:1}}}]) : 統(tǒng)計name=Jack的人數(shù)
    • 這個命令相當(dāng)于SQL中的select count(*) from user where name="Jack"
    • 我們可以使用db.user.find({name:"Jack"}).count()同樣可以查詢枷颊、
  • db.user.aggregate([{$match:{age:{$gt:20}}},{$group:{_id:"$name",sum_age:{$sum:"$age"}}}])
    • 相當(dāng)于SQL中的select _id,sum(age) as sum_age from user where age>20 group by name
  • db.user.aggregate([{$group:{_id:"$name",sum_age:{$sum:"$age"}}},{$match:{sum_age:{$gte:75}}}])
    • select _id,sum(age) as sum_age from user group by name having sum_age>=75
  • db.user.aggregate([{$match:{name:"Tom"}},{$group:{_id:"$name",sum_age:{$sum:"$age"}}},{$match:{sum_age:{$gte:75}}}])
    • select _id,sum(age) as sum_age from user where name="Tom" group by name having sum_age>=75

$limit

  • 控制顯示的條數(shù)戳杀,因為使用聚合之后,不能再使用limit()方法來限制
  • db.user.aggregate([{$group:{_id:"$name",sum_age:{$sum:"$age"}}},{$limit:1}]) : 根據(jù)姓名分組之后顯示一條數(shù)據(jù)
    • 相當(dāng)于 select _id,sum(age) as sum_age from user group by name limit 0,1
  • db.user.aggregate([{$match:{name:"Tom"}},{$group:{_id:"$name",sum_age:{$sum:"$age"}}},{$match:{sum_age:{$gte:75}}},{$skip:0},{$limit:1}])
    • select _id ,sum(age) as sum_age from user where name="Tom" group by name having age>=75 limit 0,1

$sort

  • 排序輸出
  • db.collection.aggregate([{},{},{},......,{$sort:{key:1}}])
  • db.user.aggregate([{$match:{name:"Tom"}},{$group:{_id:"$name",sum_age:{sum:"age"}}},{$match:{sum_age:{$gte:75}}},{$sort:{sum_age:1}},{$skip:0},{$limit:1}])
    • select _id ,sum(age) as sum_age from user where name="Tom" group by name having age>=75 order by sum_age asc limit 0,1

總結(jié)

  • 常用的格式: db.collection.aggregate([{$match:{key:value,...},{$group:{_id:value,..}},{$match:{key:value,....}},{$sort:{key:1,key2:-1}},{$skip:num},{$limit:num}])
    • 對應(yīng)SQL中的語句為:select _id,key1,key2 from collection where group by order by limit n,m
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末夭苗,一起剝皮案震驚了整個濱河市信卡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌题造,老刑警劉巖傍菇,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異界赔,居然都是意外死亡丢习,警方通過查閱死者的電腦和手機牵触,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來咐低,“玉大人揽思,你說我怎么就攤上這事〖粒” “怎么了绰更?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長锡宋。 經(jīng)常有香客問我儡湾,道長,這世上最難降的妖魔是什么执俩? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任徐钠,我火速辦了婚禮,結(jié)果婚禮上役首,老公的妹妹穿的比我還像新娘尝丐。我一直安慰自己,他們只是感情好衡奥,可當(dāng)我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布爹袁。 她就那樣靜靜地躺著,像睡著了一般矮固。 火紅的嫁衣襯著肌膚如雪失息。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天档址,我揣著相機與錄音盹兢,去河邊找鬼。 笑死守伸,一個胖子當(dāng)著我的面吹牛绎秒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播尼摹,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼见芹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蠢涝?” 一聲冷哼從身側(cè)響起玄呛,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惠赫,沒想到半個月后把鉴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年庭砍,在試婚紗的時候發(fā)現(xiàn)自己被綠了场晶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡怠缸,死狀恐怖诗轻,靈堂內(nèi)的尸體忽然破棺而出骑科,到底是詐尸還是另有隱情天梧,我是刑警寧澤匣屡,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布跪楞,位于F島的核電站,受9級特大地震影響臭杰,放射性物質(zhì)發(fā)生泄漏耻警。R本人自食惡果不足惜幽纷,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一疚俱、第九天 我趴在偏房一處隱蔽的房頂上張望劝术。 院中可真熱鬧,春花似錦呆奕、人聲如沸养晋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽绳泉。三九已至,卻和暖如春姆泻,著一層夾襖步出監(jiān)牢的瞬間零酪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工麦射, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蛾娶,地道東北人灯谣。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓潜秋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親胎许。 傳聞我的和親對象是個殘疾皇子峻呛,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容