
1.下載安裝
1.1.首先去官網(wǎng)下載mongodb對(duì)應(yīng)版本安裝
https://www.mongodb.com/download-center
?????解壓到目錄 例如:c:/mongo
?????創(chuàng)建文件夾用于mongodb數(shù)據(jù)存儲(chǔ)和日志存儲(chǔ) 例如:c:/mongo/data/db c:/mongo/data/log
1.2.初始化數(shù)據(jù)庫(kù)
?????打開控制臺(tái)cd到bin目錄下或者將bin目錄配置到環(huán)境變量
> cd c:/mongo/bin
> mongod –dbpath=../data/db –port=27017
?????數(shù)據(jù)庫(kù)啟動(dòng)成功 mongodb默認(rèn)端口為27017
C:\Users\maikuraki>mongod --dbpath=c:/mongo/data/db -port=27017
2018-01-27T20:36:55.680+0800 I CONTROL [initandlisten] MongoDB starting : pid=9364 port=27017 dbpath=c:/mongo/data/db 64-bit host=MySurface
2018-01-27T20:36:55.682+0800 I CONTROL [initandlisten] targetMinOS: Windows Vista/Windows Server 2008
2018-01-27T20:36:55.682+0800 I CONTROL [initandlisten] db version v3.2.4
2018-01-27T20:36:55.683+0800 I CONTROL [initandlisten] git version: e2ee9ffcf9f5a94fad76802e28cc978718bb7a30
2018-01-27T20:36:55.683+0800 I CONTROL [initandlisten] allocator: tcmalloc
2018-01-27T20:36:55.683+0800 I CONTROL [initandlisten] modules: none
2018-01-27T20:36:55.683+0800 I CONTROL [initandlisten] build environment:
2018-01-27T20:36:55.683+0800 I CONTROL [initandlisten] distarch: x86_64
2018-01-27T20:36:55.683+0800 I CONTROL [initandlisten] target_arch: x86_64
2018-01-27T20:36:55.683+0800 I CONTROL [initandlisten] options: { net: { port: 27017 }, storage: { dbPath: "c:/mongo/data/db" } }
2018-01-27T20:36:55.684+0800 I - [initandlisten] Detected data files in c:/mongo/data/db created by the 'wiredTiger' storage engine, so setting the active storage engine to 'wiredTiger'.
2018-01-27T20:36:55.685+0800 I STORAGE [initandlisten] wiredtiger_open config: create,cache_size=1G,session_max=20000,eviction=(threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB),statistics_log=(wait=0),
2018-01-27T20:36:56.618+0800 I NETWORK [HostnameCanonicalizationWorker] Starting hostname canonicalization worker
2018-01-27T20:36:56.618+0800 I FTDC [initandlisten] Initializing full-time diagnostic data capture with directory 'c:/mongo/data/db/diagnostic.data'
2018-01-27T20:36:56.624+0800 I NETWORK [initandlisten] waiting for connections on port 27017
2018-01-27T20:37:12.505+0800 I NETWORK [initandlisten] connection accepted from 127.0.0.1:61372 #1 (1 connection now open)
數(shù)據(jù)庫(kù)啟動(dòng)成功
1.3.連接數(shù)據(jù)庫(kù)
?????新開一個(gè)控制臺(tái)cd到bin目錄下
> mongo 127.0.0.1
?????連接成功后進(jìn)入shell模式 按ctrl+c退出
?????默認(rèn)會(huì)用test
C:\Users\maikuraki>mongo 127.0.0.1
MongoDB shell version: 3.2.4
connecting to: 127.0.0.1/test
>
2.mongodb基本操作
1.查看數(shù)據(jù)庫(kù)列表
> show dbs
I1 0.000GB
ci 0.000GB
local 0.000GB
user 0.000GB
>
2.選擇或創(chuàng)建數(shù)據(jù)庫(kù)進(jìn)入
選擇的數(shù)據(jù)庫(kù)不一定要存在 如果沒有該數(shù)據(jù)庫(kù)mongodb會(huì)在緩存中創(chuàng)建,當(dāng)存入數(shù)據(jù)后才會(huì)正在創(chuàng)建
> use user
switched to db user
>
3.增加插入數(shù)據(jù) (create)
創(chuàng)建一個(gè)集合叫persion
db.createCollection('persion')
如果沒有創(chuàng)建也可以直接插入保存一條數(shù)據(jù),mongodb會(huì)自動(dòng)創(chuàng)建persion的集合
> db.persion.save({name: 'json'})
>
在庫(kù)中插入一條persion的集合增加一條{name: 'tom'}的數(shù)據(jù)
> db.persion.insert({name: 'tom'})
>
save和insert的區(qū)別:若新增的數(shù)據(jù)中存在主鍵 ,insert() 會(huì)提示錯(cuò)誤,而save()
則更改原來(lái)的內(nèi)容為新內(nèi)容。
4.查看庫(kù)中的集合
> show collections
chats
persion
users
>
5.查看剛剛添加的集合中內(nèi)容 (retrieve)
db.[documentName].find()查找集合中的所有數(shù)據(jù)
> db.persion.find()
{ "_id" : ObjectId("5a6c7a7bcbeb9ed70a40a5bc"), "name" : "json" } //mongodb會(huì)自動(dòng)創(chuàng)建一條_id的索引
{ "_id" : ObjectId("5a6c7938cbeb9ed70a40a5bb"), "name" : "tom" }
>
db.[documentName].findOne()查找集合中的一條數(shù)據(jù)
> db.persion.findOne()
{ "_id" : ObjectId("5a6c7a7bcbeb9ed70a40a5bc"), "name" : "json" }
>
**db.[documentName].find().count()統(tǒng)計(jì)集合中的數(shù)據(jù)條數(shù) **
6.更新數(shù)據(jù)(update)
db.[documentName].update({查詢條件},{更新內(nèi)容})
把剛剛插入的name叫tom的更新成tom2
> db.persion.update({name: 'tom'},{name: 'tom2'})
> db.persion.find()
{ "_id" : ObjectId("5a6c7a7bcbeb9ed70a40a5bc"), "name" : "json" }
{ "_id" : ObjectId("5a6c7938cbeb9ed70a40a5bb"), "name" : "tom2" }
>
如果查詢條件的字段和要修改的字段不同則需要修改器
db.[documentName].update({查詢條件},{$set: {更新內(nèi)容}})
> db.persion.update({name: '張三'},{$set:{age: 24}})
> db.persion.find() })
{ "_id" : ObjectId("5a6c8227cbeb9ed70a40a5bd"), "age" : 24 } //這條是沒有使用修改器修改 結(jié)果name屬性沒有了
{ "_id" : ObjectId("5a6c8280cbeb9ed70a40a5be"), "name" : "張三", "age" : 24 }
>
更新所有符合要求的數(shù)據(jù)
db.[documentName].update({查詢條件},{$set: {更新內(nèi)容}},{multi,true})
> db.persion.update({name: '張三'},{$set:{age: 24}},{multi,true})
>
7.刪除(delete)
刪除庫(kù)中的集合
db.[documentName].drop()
> db.persion.drop()
刪除集合下的所有數(shù)據(jù)
db.[documentName].remove({})
> db.persion.remove({})
刪除集合下的某一條數(shù)據(jù)
db.[documentName].remove({查詢條件})
> db.persion.remove({name: '張三'})
刪除數(shù)據(jù)庫(kù)
> db.dropDatabase()
8.數(shù)據(jù)庫(kù)命名規(guī)范
- 不能是空字符串
- 不能含有' '(空格)、,、$、/、\、和\O(空字符)
- 應(yīng)該全部小寫
- 最多64個(gè)字節(jié)
- 不能與現(xiàn)有庫(kù)同名
- 帶有符號(hào)的如db-foo這樣的不能通過db.[documentName]獲取需要用db.getCollection(documentName)獲取(-會(huì)被當(dāng)成減號(hào))
3.mongodb高級(jí)操作
1.直接執(zhí)行javascript
mongodb的shell可以執(zhí)行javascript
用for循環(huán)批量插入
> for(var i = 0;i < 10; i ++){
... db.persion.insert({name: 'tom_'+ i})
... }
> db.persion.find()
{ "_id" : ObjectId("5a6c8a80c70097e60431ebc9"), "name" : "tom_0" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebca"), "name" : "tom_1" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebcb"), "name" : "tom_2" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebcc"), "name" : "tom_3" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebcd"), "name" : "tom_4" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebce"), "name" : "tom_5" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebcf"), "name" : "tom_6" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebd0"), "name" : "tom_7" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebd1"), "name" : "tom_8" }
{ "_id" : ObjectId("5a6c8a80c70097e60431ebd2"), "name" : "tom_9" }
>
2.update參數(shù)
設(shè)置參數(shù)為true,當(dāng)查詢不到的時(shí)候則自動(dòng)insert一條數(shù)據(jù)如果查詢到則做update操作
> db.persion.update({_id: 1},{_id: 1, name: 'tom'}, true)
insertOrUpdate之后再加true參數(shù) 需要配合$set修改器使用
> db.persion.update({_id: 1},{$set:{_id: 1, name: 'tom'}}, fasle, true)
3.修改器
| 修改器 | 功能 |
|---|---|
| $inc | 對(duì)指定的鍵做加法操作,如果指定的關(guān)鍵不存在,則新創(chuàng)建這個(gè)鍵,并且賦值為$inc指定的值 |
| $set | 給指定的鍵賦值,如果指定的鍵不存在,則自動(dòng)創(chuàng)建 |
| $unset | 清除一個(gè)鍵和值 |
| $push | 對(duì)數(shù)組進(jìn)行操作,push將一個(gè)元素追加到集合的末尾(不管這個(gè)元素是否存在于數(shù)組中),如果數(shù)組不存在,則首先創(chuàng)建數(shù)組,如果鍵存在值不是數(shù)組類型則會(huì)報(bào)錯(cuò) |
| $pushAll | push操作的批量版本,如果給push操作提供一個(gè)數(shù)組作為參數(shù),那么push認(rèn)為是把整個(gè)數(shù)組作為一個(gè)元素加入到指定的數(shù)組末尾 |
| $addToSet | pushAll的去重版本,即$addToSet實(shí)現(xiàn)了Java的Set集合的特性(Set中不能包含相同的元素) |
| $pop | 從數(shù)組中移除一個(gè)元素{$pop:{"key":1}}從數(shù)組末尾刪除;pop:{"key":-1}}從數(shù)組開頭刪除 |
| $pull | 刪除數(shù)組中指定元素 |
| $pullAll | 刪除數(shù)組中多個(gè)指定元素 |
| $rename | 修改指定鍵的鍵名 |
案例
$inc
> db.persion.insert({name: 'tom', age: 20})
> db.persion.find()
{ "_id" : ObjectId("5a6c93dec70097e60431ebd3"), "name" : "tom", "age" : 20 }
//找到年齡為20的任何加上1
> db.persion.update({age: 20},{$inc:{age: 1}})
> db.persion.find()
{ "_id" : ObjectId("5a6c93dec70097e60431ebd3"), "name" : "tom", "age" : 21 }
$set
> db.persion.insert({name: 'tom', age: 20})
> db.persion.find()
{ "_id" : ObjectId("5a6c93dec70097e60431ebd3"), "name" : "tom", "age" : 20 }
//更新name: tom -> jack
> db.persion.update({age: 20},{$set:{name: 'jack'}})
> db.persion.find()
{ "_id" : ObjectId("5a6c93dec70097e60431ebd3"), "name" : "jack", "age" : 20 }
$unset
> db.persion.insert({name: 'tom', age: 20})
> db.persion.find()
{ "_id" : ObjectId("5a6c93dec70097e60431ebd3"), "name" : "tom", "age" : 20 }
//刪除name屬性
> db.persion.update({age: 20},{$unset:{name: ''}})
> db.persion.find()
{ "_id" : ObjectId("5a6c93dec70097e60431ebd3"), "age" : 20 }
$push
> db.persion.insert({_id: 1, arr: [1, 2, 3]})
> db.persion.find()
{ "_id" : 1, "arr" : [ 1, 2, 3 ] }
//給arr屬性增加一個(gè)值
> db.persion.update({_id: 1}, {$push: {arr: 4}})
> db.persion.find()
{ "_id" : 1, "arr" : [ 1, 2, 3, 4 ] }
>
$pushAll
> db.persion.update({_id: 1}, {$pushAll: {arr: [5,6,7]}})
> db.persion.find()
{ "_id" : 1, "arr" : [ 1, 2, 3, 4, 5, 6, 7 ] }
>
$addToSet
如果數(shù)組中有該值則不會(huì)追加
{ "_id" : 1, "arr" : [ 1, 2, 3, 4, 5, 6, 7 ] }
> db.persion.update({_id: 1}, {$addToSet: {arr: 1}})
> db.persion.find()
{ "_id" : 1, "arr" : [ 1, 2, 3, 4, 5, 6, 7 ] }
> db.persion.update({_id: 1}, {$addToSet: {arr: 8}})
> db.persion.find()
{ "_id" : 1, "arr" : [ 1, 2, 3, 4, 5, 6, 7, 8 ] }
$pop
{ "_id" : 1, "arr" : [ 1, 2, 3 ] }
> db.persion.update({_id:1},{$pop:{arr:1}})
> db.persion.find()
{ "_id" : 1, "arr" : [ 1, 2 ] }
>
{ "_id" : 1, "arr" : [ 1, 2, 3 ] }
> db.persion.update({_id:1},{$pop:{arr:-1}})
> db.persion.find()
{ "_id" : 1, "arr" : [ 2, 3 ] }
>
$pull
{ "_id" : 1, "arr" : [ 1, 2, 3 ] }
> db.persion.update({_id:1},{$pull:{arr:2}})
> db.persion.find()
{ "_id" : 1, "arr" : [ 1, 3 ] }
>
$pullAll
{ "_id" : 1, "arr" : [ 1, 2, 3 ] }
> db.persion.update({_id:1},{$pullAll:{arr:[2,3]}})
> db.persion.find()
{ "_id" : 1, "arr" : [ 1 ] }
>
$rename
{ "_id" : 1, "arr" : [ 1, 2, 3 ] }
> db.persion.update({_id:1},{$rename:{arr:'arr2'}})
> db.persion.find()
{ "_id" : 1, "arr2" : [ 1 ] }
>
4.高級(jí)查詢
1.指定返回的key
db.[documentName].find({條件},{key指定})
插入二十條測(cè)試數(shù)據(jù)
> for(var i=0;i < 20;i++){
... db.persion.insert({name: 'tom_'+i,age: 24+i,country: (i%2 == 0)?'USA':'China'})
... }
查找country = USA的數(shù)據(jù)且只返回name(mongodb會(huì)默認(rèn)返回_id,這里設(shè)置 _id:0不返還 _id)
> db.persion.find({country:'USA'},{_id:0,name:1})
{ "name" : "tom_0" }
{ "name" : "tom_2" }
{ "name" : "tom_4" }
{ "name" : "tom_6" }
{ "name" : "tom_8" }
{ "name" : "tom_10" }
{ "name" : "tom_12" }
{ "name" : "tom_14" }
{ "name" : "tom_16" }
{ "name" : "tom_18" }
>
2.常用查詢條件
對(duì)比查詢
| 條件符 | 功能 | 示例 | 說(shuō)明 |
|---|---|---|---|
| $gt | > | db.persion.find({age: {$gt: 28}}, {_id:0,name: 1}) | 查詢age大于28的記錄只返回name |
| $gte | >= | db.persion.find({age: {$gte: 28}}, {_id:0,name: 1}) | 查詢age大于等于28的記錄只返回name |
| $lt | < | db.persion.find({age: {$lt: 28}}, {_id:0,name: 1}) | 查詢age小于28的記錄 |
| $lte | <= | db.persion.find({age: {$lte: 28}}, {_id:0,name: 1}) | 查詢age小于等于28的記錄 |
| $ne | != | db.persion.find({country: {$ne: 'USA'}}, {_id:0,name: 1}) | 查詢country不等于USA的記錄 |
| $eq | = | db.persion.find({country: {$eq: 'USA'}}, {_id:0,name: 1}) | 查詢country等于USA的記錄 |
| $in | in | db.persion.find({country: {$in: ['USA','China']}}, {_id:0,name: 1}) | 查詢country包含USA或China的記錄 |
| $nin | not in | db.persion.find({country: {$nin: ['USA','China']}}, {_id:0,name: 1}) | 查詢country不包含USA或China的記錄 |
邏輯查詢
| 條件符 | 功能 | 示例 | 說(shuō)明 |
|---|---|---|---|
| $or | or | db.persion.find({$or: [{age: {$gt: 39}}, {age: {$lt: 28}}]}, {_id:0,name: 1}) | 查詢age大于39或者age小于28的記錄 |
| $nor | not or | db.persion.find({$nor: [{age: {$gt: 39}}, {age: {$lt: 28}}]}, {_id:0,name: 1}) | 查詢age小于等于39且age大于等于28的記錄 |
| $and | and | db.persion.find({$and: [{age: {$lt: 39}}, {age: {$gt: 28}}]}, {_id:0,name: 1}) | 查詢age大于28且age小于39的記錄等價(jià)于db.persion.find({age: {$gt: 28, $lt: 39}}, { _id:0,name: 1}) |
| $not | not | db.persion.find({age: {$not: {$gt: 28}}}, { _id:0,name: 1}) | 查詢age不大于28的記錄 |
數(shù)組查詢
插入測(cè)試數(shù)據(jù)
> db.persion.insert({book: ['JS','PHP','JAVA']})
> db.persion.insert({book: ['JS','PHP','JAVA','NODEJS']})
| 條件符 | 功能 | 示例 | 說(shuō)明 |
|---|---|---|---|
| $all | 查詢數(shù)組包含的 | db.persion.find({book:{$all: ['NODEJS']}}) | 查詢所有集合中book數(shù)組里包含NODEJS的結(jié)果 |
| $size | 查詢數(shù)組長(zhǎng)度 | db.persion.find({book:{$size: 3}}) | 查詢所有集合中book數(shù)組長(zhǎng)度為3的結(jié)果 |
| $elemMatch | 組合查詢 | db.persion.find({book: {$elemMatch: {$in: ['PHP','NODEJS']}}}) | 查找book中包含PHP或者NODEJS的結(jié)果 |
分頁(yè)與排序
limit 返回指定數(shù)據(jù)條數(shù)
> db.persion.find({$or: [{country: 'USA'},{country: 'China'}]}).limit(5)
skip返回指定跨度的數(shù)據(jù)
跨越數(shù)據(jù)量大的時(shí)候會(huì)有性能問題
> db.persion.find({$or: [{country: 'USA'},{country: 'China'}]}).limit(5).skip(10)
sort 返回按照key排序的數(shù)據(jù)[1,-1]
> db.persion.find({$or: [{country: 'USA'},{country: 'China'}]}).limit(5).skip(10).sort({age: -1})
游標(biāo)
利用游標(biāo)遍歷數(shù)據(jù)
var persions = db.persion.find();
while(persions.hasNext()) {
obj = persions.next();
print(obj.name)
}
查詢快照
> db.persion.find({$query: {name: 'tom_1'}, $snapshot: true})
高級(jí)查詢選項(xiàng)
- $query
- $orderby
- $maxsan: integer最多掃描文檔數(shù)
- $min: doc查詢開始
- $max: doc查詢結(jié)束
- $hint: doc使用哪個(gè)索引
- $explain: boolean 統(tǒng)計(jì)
- $snapshot: boolean 一致快照
[obj1, obj2, obj3, obj4]
游標(biāo)讀取時(shí)obj1->obj2 當(dāng)讀取到obj2時(shí)對(duì)obj2進(jìn)行操作導(dǎo)致obj占用空間變大mongodb會(huì)將它放到最后此時(shí)排列為: [obj1, obj3, obj4, obj2]
游標(biāo)接下去讀取將會(huì)讀到obj4此時(shí)obj3就漏讀了 使用快照可以避免這個(gè)問題
3.索引
建立索引1正序-1倒敘
數(shù)量級(jí)大時(shí)提升查詢時(shí)間 但會(huì)影響插入時(shí)間
> db.persion.ensureIndex({age: 1},{background: true}) //后臺(tái)執(zhí)行
建立索引并指定索引名稱
> db.persion.ensureIndex({age: 1}, {name: 'ageIndex'})
唯一索引(不能插入重復(fù)值)
> db.persion.ensureIndex({age: 1}, {unique: true})
剔除重復(fù)數(shù)據(jù)
> db.persion.ensureIndex({age: 1}, {unique: true,dropDups: true})
查詢時(shí)指定索引
> db.persion.find({name: 'tom'}).hint({age: -1})
查看查詢信息
> db.persion.find({name: 'tom'}).expain()
查看索引
> db.system.indexes.find()
> db.system.namespaces.find()
刪除索引
> db.runCommand({dropIndexes: 'age', index: 'ageIndex'})
> db.runCommand({dropIndexes: 'age', index: '*'})
4.空間索引(2D索引)
測(cè)試數(shù)據(jù)插入data中的每一條數(shù)據(jù)
var data = [
key: {
x: 0,
y: 0
},
key: {
x: 10,
y: 15,
},
....
{
x: 200,
y: 300
}
]
> db.map.ensureIndex({key: '2d', {min: -1, max: 200})
建立空間索引后查詢距離(50, 100)最近的三個(gè)數(shù)據(jù)
> db.map.find({key: {$near: [50, 100]}}).limit(3)
查詢(50, 50)點(diǎn)和(200,200)點(diǎn)為對(duì)角線的正方形中所有的數(shù)據(jù)點(diǎn)
> db.map.find({key:{$widthin: {$box: [[50,50],[200,200]]}}})
查詢已(100,120)為圓心50為半徑內(nèi)部的所有點(diǎn)數(shù)據(jù)
> db.map.find({key: {$widthin: {$center: [[100,120],50]}}})
5.聚合(aggregate)
MongoDB中聚合主要用于處理數(shù)據(jù)(諸如統(tǒng)計(jì)平均值,求和等),并返回計(jì)算后的數(shù)據(jù)結(jié)果。
db.[documentName].aggregate(聚合選項(xiàng))
插入測(cè)試數(shù)據(jù)
var data = [
{
name: 'tom',
age: 22,
favorite: ['JAVA', 'NODE', 'MONGO', 'GO']
},
{
name: 'jack',
age: 26,
favorite: ['PHP', 'MONGO', 'GO']
},
{
name: 'bill',
age: 23,
favorite: ['PYTHON', 'RUBY', 'MYSQL', 'GO','ANDROID']
},
{
name: 'james',
age: 23,
favorite: ['PHP', 'MONGO', 'GO']
}
]
for(var i = 0;i < data.length; i++) {
db.persion.insert(data[i])
}
| 條件符 | 功能 | 示例 | 說(shuō)明 |
|---|---|---|---|
| $sum | 求和 | db.persion.aggregate([{$group: {_id: '$age', num_total: {$sum: '$age'}}}]) | 以age為_id求所有age相同的數(shù)據(jù)中age的總和 |
| $avg | 平均值 | db.persion.aggregate([{$group: {_id: '$favorite', avg: {$avg: '$age'}}}]) | 以favorite為_id求所有favorite相同的人的age平均值 |
| $min | 集合中最小值 | db.presion.aggregate([{$group: {_id: '$favorite', min: {$min: '$age'}}}]) | 以favorite為_id求favorite相同的人里age最小的 |
| $max | 集合中最小值 | db.presion.aggregate([{$group: {_id: '$favorite', max: {$max: '$age'}}}]) | 以favorite為_id求favorite相同的人里age最小的 |
| $push | 在結(jié)果文檔中插入值到一個(gè)數(shù)組中 | db.persion.aggregate([{$group: {_id: '$favorite', _age: {$push: '$age'}}}]) | 統(tǒng)計(jì)所有favorite相同的人的age存入_age數(shù)組中 |
| $addToSet | 在結(jié)果文檔中插入值到一個(gè)數(shù)組中,但不創(chuàng)建副本 | db.persion.aggregate([{$group: {_id: '$favorite', _age: {$addToSet: '$age'}}}]) | 統(tǒng)計(jì)所有favorite相同的人的age存入_age數(shù)組中,如果_age數(shù)組已存在相同的值則不會(huì)存入 |
| $first | 根據(jù)資源文檔的排序獲取第一個(gè)文檔數(shù)據(jù) | db.persion.aggregate([{$group: {_id: '$favorite', first_name: {$first: '$name'}}}]) | 相同favorite中第一個(gè)出現(xiàn)的人的name |
| $last | 根據(jù)資源文檔的排序獲取第一個(gè)文檔數(shù)據(jù) | db.persion.aggregate([{$group: {_id: '$favorite', first_name: {$last: '$name'}}}]) | 相同favorite中最后個(gè)出現(xiàn)的人的name |
$sum
> db.persion.aggregate([{$group: {_id: '$age', num_total: {$sum: '$age'}}}])
{ "_id" : 23, "num_total" : 46 } //23出現(xiàn)兩次總和是46
{ "_id" : 26, "num_total" : 26 }
{ "_id" : 22, "num_total" : 22 }
>
$avg
> db.persion.aggregate([{$group: {_id: '$favorite', avg: {$avg: '$age'}}}])
{ "_id" : [ "JAVA", "NODE", "MONGO", "GO" ], "avg" : 22 }
{ "_id" : [ "PHP", "MONGO", "GO" ], "avg" : 24.5 }
{ "_id" : [ "PYTHON", "RUBY", "MYSQL", "GO", "ANDROID" ], "avg" : 23 }
>
$min
> db.persion.aggregate([{$group: {_id: '$favorite', min: {$min: '$age'}}}])
{ "_id" : [ "JAVA", "NODE", "MONGO", "GO" ], "min" : 22 }
{ "_id" : [ "PHP", "MONGO", "GO" ], "min" : 23 }
{ "_id" : [ "PYTHON", "RUBY", "MYSQL", "GO", "ANDROID" ], "min" : 23 }
$max
> db.persion.aggregate([{$group: {_id: '$favorite', max: {$max: '$age'}}}])
{ "_id" : [ "JAVA", "NODE", "MONGO", "GO" ], "max" : 22 }
{ "_id" : [ "PHP", "MONGO", "GO" ], "max" : 26 }
{ "_id" : [ "PYTHON", "RUBY", "MYSQL", "GO", "ANDROID" ], "max" : 23 }
>
$push
再插入一條測(cè)試數(shù)據(jù)
> db.persion.insert({
name: 'jam',
age: 26,
favorite: ['PHP', 'MONGO', 'GO'],
_age: [23],
})
> db.persion.aggregate([{$group: {_id: '$favorite', _age: {$push: '$age'}}}])
{ "_id" : [ "JAVA", "NODE", "MONGO", "GO" ], "_age" : [ 22 ] }
{ "_id" : [ "PHP", "MONGO", "GO" ], "_age" : [ 26, 23, 26 ] }
{ "_id" : [ "PYTHON", "RUBY", "MYSQL", "GO", "ANDROID" ], "_age" : [ 23 ] }
>
$addToSet
> db.persion.aggregate([{$group: {_id: '$favorite', _age: {$addToSet: '$age'}}}])
{ "_id" : [ "JAVA", "NODE", "MONGO", "GO" ], "_age" : [ 22 ] }
{ "_id" : [ "PHP", "MONGO", "GO" ], "_age" : [ 23, 26 ] }
{ "_id" : [ "PYTHON", "RUBY", "MYSQL", "GO", "ANDROID" ], "_age" : [ 23 ] }
>
$first
> db.persion.aggregate([{$group: {_id: '$favorite', first_name: {$first: '$name'}}}])
{ "_id" : [ "JAVA", "NODE", "MONGO", "GO" ], "first_name" : "tom" }
{ "_id" : [ "PHP", "MONGO", "GO" ], "first_name" : "jack" }
{ "_id" : [ "PYTHON", "RUBY", "MYSQL", "GO", "ANDROID" ], "first_name" : "bill" }
>
$last
> db.persion.aggregate([{$group: {_id: '$favorite', first_name: {$last: '$name'}}}])
{ "_id" : [ "JAVA", "NODE", "MONGO", "GO" ], "first_name" : "tom" }
{ "_id" : [ "PHP", "MONGO", "GO" ], "first_name" : "jam" }
{ "_id" : [ "PYTHON", "RUBY", "MYSQL", "GO", "ANDROID" ], "first_name" : "bill" }
>
管道
聚合管道:將當(dāng)命令前輸出的結(jié)果作為下一個(gè)命令的參數(shù) 管道操作可以重復(fù)
表達(dá)式:處理輸入文檔并輸出。表達(dá)式是無(wú)狀態(tài)的,只能用于計(jì)算當(dāng)前聚合管道的文檔,不能處理其它的文檔。
常用操作:
- $project 修改輸入文檔的結(jié)構(gòu)??梢杂脕?lái)重命名、增加或刪除域,也可以用于創(chuàng)建計(jì)算結(jié)果以及嵌套文檔
- $match 用于過濾數(shù)據(jù),只輸出符合條件的文檔。$match使用MongoDB的標(biāo)準(zhǔn)查詢操作
- $limit 用來(lái)限制MongoDB聚合管道返回的文檔數(shù)
- $skip 在聚合管道中跳過指定數(shù)量的文檔,并返回余下的文檔
- $unwind 將文檔中的某一個(gè)數(shù)組類型字段拆分成多條,每條包含數(shù)組中的一個(gè)值
- $group 將集合中的文檔分組,可用于統(tǒng)計(jì)結(jié)果
- $sort 將輸入文檔排序后輸出
$project
值查找顯示name和age屬性
> db.persion.aggregate({$project: {name: 1, age: 1}})
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7d"), "name" : "tom", "age" : 22 }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7e"), "name" : "jack", "age" : 26 }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7f"), "name" : "bill", "age" : 23 }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d80"), "name" : "james", "age" : 23 }
{ "_id" : ObjectId("5a6dc2db3a8a0d47b8ee6d81"), "name" : "jam", "age" : 26 }
$match
先匹配age大于22的數(shù)據(jù) 然后用這些數(shù)據(jù)統(tǒng)計(jì)favorite相同的人中出現(xiàn)的年齡數(shù)
> db.persion.aggregate([{$match: {age: {$gt: 22}}}, {$group: {_id: '$favorite', _age: {$push: '$age'}}}])
{ "_id" : [ "PHP", "MONGO", "GO" ], "_age" : [ 26, 23, 26 ] }
{ "_id" : [ "PYTHON", "RUBY", "MYSQL", "GO", "ANDROID" ], "_age" : [ 23 ] }
>
$skip
跨過前兩條數(shù)據(jù)
> db.persion.aggregate({$skip: 2})
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7f"), "name" : "bill", "age" : 23, "favorite" : [ "PYTHON", "RUBY", "MYSQL", "GO", "ANDROID" ] }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d80"), "name" : "james", "age" : 23, "favorite" : [ "PHP", "MONGO", "GO" ] }
{ "_id" : ObjectId("5a6dc2db3a8a0d47b8ee6d81"), "name" : "jam", "age" : 26, "favorite" : [ "PHP", "MONGO", "GO" ], "_age" : [ 23 ] }
>
$unwind
將favorite拆開
> db.persion.aggregate([{$unwind: '$favorite'}])
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7d"), "name" : "tom", "age" : 22, "favorite" : "JAVA" }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7d"), "name" : "tom", "age" : 22, "favorite" : "NODE" }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7d"), "name" : "tom", "age" : 22, "favorite" : "MONGO" }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7d"), "name" : "tom", "age" : 22, "favorite" : "GO" }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7e"), "name" : "jack", "age" : 26, "favorite" : "PHP" }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7e"), "name" : "jack", "age" : 26, "favorite" : "MONGO" }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7e"), "name" : "jack", "age" : 26, "favorite" : "GO" }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7f"), "name" : "bill", "age" : 23, "favorite" : "PYTHON" }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7f"), "name" : "bill", "age" : 23, "favorite" : "RUBY" }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7f"), "name" : "bill", "age" : 23, "favorite" : "MYSQL" }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7f"), "name" : "bill", "age" : 23, "favorite" : "GO" }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7f"), "name" : "bill", "age" : 23, "favorite" : "ANDROID" }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d80"), "name" : "james", "age" : 23, "favorite" : "PHP" }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d80"), "name" : "james", "age" : 23, "favorite" : "MONGO" }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d80"), "name" : "james", "age" : 23, "favorite" : "GO" }
{ "_id" : ObjectId("5a6dc2db3a8a0d47b8ee6d81"), "name" : "jam", "age" : 26, "favorite" : "PHP", "_age" : [ 23 ] }
{ "_id" : ObjectId("5a6dc2db3a8a0d47b8ee6d81"), "name" : "jam", "age" : 26, "favorite" : "MONGO", "_age" : [ 23 ] }
{ "_id" : ObjectId("5a6dc2db3a8a0d47b8ee6d81"), "name" : "jam", "age" : 26, "favorite" : "GO", "_age" : [ 23 ] }
>
$group
略...
$sort
按照年齡排序 1正序-1倒序
> db.persion.aggregate([{$sort: {age: 1}}])
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7d"), "name" : "tom", "age" : 22, "favorite" : [ "JAVA", "NODE", "MONGO", "GO" ] }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7f"), "name" : "bill", "age" : 23, "favorite" : [ "PYTHON", "RUBY", "MYSQL", "GO", "ANDROID" ] }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d80"), "name" : "james", "age" : 23, "favorite" : [ "PHP", "MONGO", "GO" ] }
{ "_id" : ObjectId("5a6dbb6a3a8a0d47b8ee6d7e"), "name" : "jack", "age" : 26, "favorite" : [ "PHP", "MONGO", "GO" ] }
{ "_id" : ObjectId("5a6dc2db3a8a0d47b8ee6d81"), "name" : "jam", "age" : 26, "favorite" : [ "PHP", "MONGO", "GO" ], "_age" : [ 23 ] }
>