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集合不存在,那么就會新建一個,這個方法默認會為我們插入一個_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為插入,默認是false,不插入。
  • multi : 可選,mongodb 默認是false,只更新找到的第一條記錄,如果這個參數(shù)為true,就把按條件查出來多條記錄全部更新。
  • writeConcern :可選,拋出異常的級別。

實例

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

刪除文檔

  • 刪除格式,默認是刪除多條,但是我們可以設(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ù)即可(默認省略)

插入數(shù)據(jù)(準備)

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>

指定顯示字段

  • 默認顯示全部的字段,但是我們可以指定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" 默認值為false
unique Boolean 建立的索引是否唯一。指定為true創(chuàng)建唯一索引。默認值為false.
name string 索引的名稱。如果未指定,MongoDB的通過連接索引的字段名和排序順序生成一個索引名稱。
dropDups Boolean 在建立唯一索引時是否刪除重復(fù)記錄,指定 true 創(chuàng)建唯一索引。默認值為 false.
sparse Boolean 對文檔中不存在的字段數(shù)據(jù)不啟用索引;這個參數(shù)需要特別注意,如果設(shè)置為true的話,在索引字段中不會查詢出不包含對應(yīng)字段的文檔.。默認值為 false.
expireAfterSeconds integer 指定一個以秒為單位的數(shù)值,完成 TTL設(shè)定,設(shè)定集合的生存時間。
v index version 索引的版本號。默認的索引版本取決于mongod創(chuàng)建索引時運行的版本。
weights document 索引權(quán)重值,數(shù)值在 1 到 99,999 之間,表示該索引相對于其他索引字段的得分權(quán)重。
default_language string 對于文本索引,該參數(shù)決定了停用詞及詞干和詞器的規(guī)則的列表。 默認為英語
language_override string 對于文本索引,該參數(shù)指定了包含在文檔中的字段名,語言覆蓋默認的language,默認值為 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 }

常用的聚合

表達式 描述 實例
$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ù)的。

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

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

  • $project:修改輸入文檔的結(jié)構(gòu)??梢杂脕碇孛?、增加或刪除域,也可以用于創(chuàng)建計算結(jié)果以及嵌套文檔。
  • $match:用于過濾數(shù)據(jù),只輸出符合條件的文檔。$match使用MongoDB的標準查詢操作。
  • $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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容