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})
,這里只會顯示_id
和name
這兩個字段,其他的字段都是不會顯示的
-
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ù)列表如下:
db.user.find().pretty()
: 這里沒有指定查詢條件瓦宜,那么就是查詢?nèi)?/li>
projection
來顯示指定的字段inclusion模式
岭妖,指定返回的鍵临庇,比如db.user.find({},{name:1})
,這里只會顯示_id
和name
這兩個字段,其他的字段都是不會顯示的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
字段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}]})
: 和上面一樣的效果
db.user.find({$or:[{expression1},{expression2},{expression3}......]})
-
db.user.find({$or:[{name:"Jack"},{age:25}]})
: 查找name=Jack或者age=25
的文檔信息
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
的信息db.user.find().limit(2)
: 只顯示兩條記錄db.user.find({name:"Jack"}).limit(2)
db.user.find().skip(10)
: 跳過前面的十條記錄废离,顯示后面的select * from user limit 20,5
db.user.find().skip(20).limit(5)
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降序排列sort()
--- > skip()
----> limit()
,這個相當(dāng)于SQL中的select * from name where group by having order by limit m,n
這種順序一樣in
db.user.find({age:{$in:[22,33,44]}})
: 查找age in (22,33,44)之中的任意一個
not in
db.user.find({age:{$nin:[22,33,44]}})
db.user.find({sex:{$exists:false}})
: 查找不存在sex
這個字段的文檔$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 ] }
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([{ |
$avg | 計算平均值 | db.mycol.aggregate([{ |
$min | 獲取集合中所有文檔對應(yīng)值得最小值啦租。 | db.mycol.aggregate([{ |
$max | 獲取集合中所有文檔對應(yīng)值得最大值。 | db.mycol.aggregate([{ |
$push | 在結(jié)果文檔中插入值到一個數(shù)組中荒揣。 | db.mycol.aggregate([{ |
$addToSet | 在結(jié)果文檔中插入值到一個數(shù)組中,但不創(chuàng)建副本系任。 | db.mycol.aggregate([{ |
$first | 根據(jù)資源文檔的排序獲取第一個文檔數(shù)據(jù)恳蹲。 | db.mycol.aggregate([{ |
$last | 根據(jù)資源文檔的排序獲取最后一個文檔數(shù)據(jù) | db.mycol.aggregate([{ |
管道
管道在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()
同樣可以查詢枷颊、
- 這個命令相當(dāng)于SQL中的
-
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
- 相當(dāng)于SQL中的
-
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
- 相當(dāng)于
-
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
- 對應(yīng)SQL中的語句為: