1.下载安装
1.1.首先去官网下载mongodb对应版本安装
https://www.mongodb.com/download-center
解压到目录 例如:c:/mongo
创建文件夹用于mongodb数据存储和日志存储 例如:c:/mongo/data/db c:/mongo/data/log
1.2.初始化数据库
打开控制台cd到bin目录下或者将bin目录配置到环境变量
> cd c:/mongo/bin
> mongod –dbpath=../data/db –port=27017
数据库启动成功 mongodb默认端口为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)
数据库启动成功
1.3.连接数据库
新开一个控制台cd到bin目录下
> mongo 127.0.0.1
连接成功后进入shell模式 按ctrl+c退出
默认会用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.查看数据库列表
> show dbs
I1 0.000GB
ci 0.000GB
local 0.000GB
user 0.000GB
>
2.选择或创建数据库进入
选择的数据库不一定要存在 如果没有该数据库mongodb会在缓存中创建,当存入数据后才会正在创建
> use user
switched to db user
>
3.增加插入数据 (create)
创建一个集合叫persion
db.createCollection('persion')
如果没有创建也可以直接插入保存一条数据,mongodb会自动创建persion的集合
> db.persion.save({name: 'json'})
>
在库中插入一条persion的集合增加一条{name: ‘tom’}的数据
> db.persion.insert({name: 'tom'})
>
**save和insert的区别:若新增的数据中存在主键 ,insert() 会提示错误,而save()
则更改原来的内容为新内容。**
4.查看库中的集合
> show collections
chats
persion
users
>
5.查看刚刚添加的集合中内容 (retrieve)
db.[documentName].find()查找集合中的所有数据
> db.persion.find()
{ "_id" : ObjectId("5a6c7a7bcbeb9ed70a40a5bc"), "name" : "json" } //mongodb会自动创建一条_id的索引
{ "_id" : ObjectId("5a6c7938cbeb9ed70a40a5bb"), "name" : "tom" }
>
db.[documentName].findOne()查找集合中的一条数据
> db.persion.findOne()
{ "_id" : ObjectId("5a6c7a7bcbeb9ed70a40a5bc"), "name" : "json" }
>
db.[documentName].find().count()统计集合中的数据条数
6.更新数据(update)
db.[documentName].update({查询条件},{更新内容})
把刚刚插入的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: {更新内容}})
> db.persion.update({name: '张三'},{$set:{age: 24}})
> db.persion.find() })
{ "_id" : ObjectId("5a6c8227cbeb9ed70a40a5bd"), "age" : 24 } //这条是没有使用修改器修改 结果name属性没有了
{ "_id" : ObjectId("5a6c8280cbeb9ed70a40a5be"), "name" : "张三", "age" : 24 }
>
更新所有符合要求的数据
db.[documentName].update({查询条件},{$set: {更新内容}},{multi,true})
> db.persion.update({name: '张三'},{$set:{age: 24}},{multi,true})
>
7.删除(delete)
删除库中的集合
db.[documentName].drop()
> db.persion.drop()
删除集合下的所有数据
db.[documentName].remove({})
> db.persion.remove({})
删除集合下的某一条数据
db.[documentName].remove({查询条件})
> db.persion.remove({name: '张三'})
删除数据库
> db.dropDatabase()
8.数据库命名规范
- 不能是空字符串
- 不能含有’ ‘(空格)、,、$、/、、和O(空字符)
- 应该全部小写
- 最多64个字节
- 不能与现有库同名
- 带有符号的如db-foo这样的不能通过db.[documentName]获取需要用db.getCollection(documentName)获取(-会被当成减号)
3.mongodb高级操作
1.直接执行javascript
mongodb的shell可以执行javascript
用for循环批量插入
> 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参数
设置参数为true,当查询不到的时候则自动insert一条数据如果查询到则做update操作
> db.persion.update({_id: 1},{_id: 1, name: 'tom'}, true)
insertOrUpdate之后再加true参数 需要配合$set修改器使用
> db.persion.update({_id: 1},{$set:{_id: 1, name: 'tom'}}, fasle, true)
3.修改器
修改器 | 功能 |
---|---|
$inc | 对指定的键做加法操作,如果指定的关键不存在,则新创建这个键,并且赋值为$inc指定的值 |
$set | 给指定的键赋值,如果指定的键不存在,则自动创建 |
$unset | 清除一个键和值 |
$push | 对数组进行操作,push将一个元素追加到集合的末尾(不管这个元素是否存在于数组中),如果数组不存在,则首先创建数组,如果键存在值不是数组类型则会报错 |
$pushAll | push操作的批量版本,如果给push操作提供一个数组作为参数,那么push认为是把整个数组作为一个元素加入到指定的数组末尾 |
$addToSet | pushAll的去重版本,即$addToSet实现了Java的Set集合的特性(Set中不能包含相同的元素) |
$pop | 从数组中移除一个元素{$pop:{“key”:1}}从数组末尾删除;pop:{“key”:-1}}从数组开头删除 |
$pull | 删除数组中指定元素 |
$pullAll | 删除数组中多个指定元素 |
$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属性增加一个值
> 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
如果数组中有该值则不会追加
{ "_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.高级查询
1.指定返回的key
db.[documentName].find({条件},{key指定})
插入二十条测试数据
> for(var i=0;i < 20;i++){
... db.persion.insert({name: 'tom_'+i,age: 24+i,country: (i%2 == 0)?'USA':'China'})
... }
查找country = USA的数据且只返回name(mongodb会默认返回_id,这里设置 _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.常用查询条件
对比查询
条件符 | 功能 | 示例 | 说明 |
---|---|---|---|
$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的记录 |
逻辑查询
条件符 | 功能 | 示例 | 说明 |
---|---|---|---|
$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的记录等价于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的记录 |
数组查询
插入测试数据
> db.persion.insert({book: ['JS','PHP','JAVA']})
> db.persion.insert({book: ['JS','PHP','JAVA','NODEJS']})
条件符 | 功能 | 示例 | 说明 |
---|---|---|---|
$all | 查询数组包含的 | db.persion.find({book:{$all: [‘NODEJS’]}}) | 查询所有集合中book数组里包含NODEJS的结果 |
$size | 查询数组长度 | db.persion.find({book:{$size: 3}}) | 查询所有集合中book数组长度为3的结果 |
$elemMatch | 组合查询 | db.persion.find({book: {$elemMatch: {\$in: [‘PHP’,’NODEJS’]}}}) | 查找book中包含PHP或者NODEJS的结果 |
分页与排序
limit 返回指定数据条数
> db.persion.find({$or: [{country: 'USA'},{country: 'China'}]}).limit(5)
skip返回指定跨度的数据
跨越数据量大的时候会有性能问题
> db.persion.find({$or: [{country: 'USA'},{country: 'China'}]}).limit(5).skip(10)
sort 返回按照key排序的数据[1,-1]
> db.persion.find({$or: [{country: 'USA'},{country: 'China'}]}).limit(5).skip(10).sort({age: -1})
游标
利用游标遍历数据
var persions = db.persion.find();
while(persions.hasNext()) {
obj = persions.next();
print(obj.name)
}
查询快照
> db.persion.find({$query: {name: 'tom_1'}, $snapshot: true})
高级查询选项
- $query
- $orderby
- $maxsan: integer最多扫描文档数
- $min: doc查询开始
- $max: doc查询结束
- $hint: doc使用哪个索引
- $explain: boolean 统计
- $snapshot: boolean 一致快照
[obj1, obj2, obj3, obj4]
游标读取时obj1->obj2 当读取到obj2时对obj2进行操作导致obj占用空间变大mongodb会将它放到最后此时排列为: [obj1, obj3, obj4, obj2]
游标接下去读取将会读到obj4此时obj3就漏读了 使用快照可以避免这个问题
3.索引
建立索引1正序-1倒叙
数量级大时提升查询时间 但会影响插入时间
> db.persion.ensureIndex({age: 1},{background: true}) //后台执行
建立索引并指定索引名称
> db.persion.ensureIndex({age: 1}, {name: 'ageIndex'})
唯一索引(不能插入重复值)
> db.persion.ensureIndex({age: 1}, {unique: true})
剔除重复数据
> db.persion.ensureIndex({age: 1}, {unique: true,dropDups: true})
查询时指定索引
> 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索引)
测试数据插入data中的每一条数据
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)最近的三个数据
> db.map.find({key: {$near: [50, 100]}}).limit(3)
查询(50, 50)点和(200,200)点为对角线的正方形中所有的数据点
> db.map.find({key:{$widthin: {$box: [[50,50],[200,200]]}}})
查询已(100,120)为圆心50为半径内部的所有点数据
> db.map.find({key: {$widthin: {$center: [[100,120],50]}}})
5.聚合(aggregate)
MongoDB中聚合主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。
db.[documentName].aggregate(聚合选项)
插入测试数据
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])
}
条件符 | 功能 | 示例 | 说明 |
---|---|---|---|
$sum | 求和 | db.persion.aggregate([{$group: {\_id: ‘\$age’, num_total: {$sum: ‘$age’}}}]) | 以age为_id求所有age相同的数据中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 | 在结果文档中插入值到一个数组中 | db.persion.aggregate([{$group: {_id: ‘$favorite’, _age: {$push: ‘$age’}}}]) | 统计所有favorite相同的人的age存入_age数组中 |
$addToSet | 在结果文档中插入值到一个数组中,但不创建副本 | db.persion.aggregate([{$group: {_id: ‘$favorite’, _age: {$addToSet: ‘$age’}}}]) | 统计所有favorite相同的人的age存入_age数组中,如果_age数组已存在相同的值则不会存入 |
$first | 根据资源文档的排序获取第一个文档数据 | db.persion.aggregate([{$group: {_id: ‘$favorite’, first_name: {$first: ‘$name’}}}]) | 相同favorite中第一个出现的人的name |
$last | 根据资源文档的排序获取第一个文档数据 | db.persion.aggregate([{$group: {_id: ‘$favorite’, first_name: {$last: ‘$name’}}}]) | 相同favorite中最后个出现的人的name |
$sum
> db.persion.aggregate([{$group: {_id: '$age', num_total: {$sum: '$age'}}}])
{ "_id" : 23, "num_total" : 46 } //23出现两次总和是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
再插入一条测试数据
> 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" }
>
管道
聚合管道:将当命令前输出的结果作为下一个命令的参数 管道操作可以重复
表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
常用操作:
- $project 修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档
- $match 用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作
- $limit 用来限制MongoDB聚合管道返回的文档数
- $skip 在聚合管道中跳过指定数量的文档,并返回余下的文档
- $unwind 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值
- $group 将集合中的文档分组,可用于统计结果
- $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的数据 然后用这些数据统计favorite相同的人中出现的年龄数
> 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
跨过前两条数据
> 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 ] }
>