2

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.数据库命名规范

  1. 不能是空字符串
  2. 不能含有' '(空格)、,、$、/、、和O(空字符)
  3. 应该全部小写
  4. 最多64个字节
  5. 不能与现有库同名
  6. 带有符号的如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({&dollar;or: [{age: {&dollar;gt: 39}}, {age: {$lt: 28}}]}, {_id:0,name: 1}) 查询age大于39或者age小于28的记录
$nor not or db.persion.find({&dollar;nor: [{age: {&dollar;gt: 39}}, {age: {$lt: 28}}]}, {_id:0,name: 1}) 查询age小于等于39且age大于等于28的记录
$and and db.persion.find({&dollar;and: [{age: {&dollar;lt: 39}}, {age: {&dollar;gt: 28}}]}, {_id:0,name: 1}) 查询age大于28且age小于39的记录等价于db.persion.find({age: {&dollar;gt: 28, $lt: 39}}, { _id:0,name: 1})
$not not db.persion.find({age: {&dollar;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: {&dollar;sum: '&dollar;age'}}}]) 以age为_id求所有age相同的数据中age的总和
$avg 平均值 db.persion.aggregate([{&dollar;group: {_id: '&dollar;favorite', avg: {$avg: '\$age'}}}]) 以favorite为_id求所有favorite相同的人的age平均值
$min 集合中最小值 db.presion.aggregate([{&dollar;group: {_id: '&dollar;favorite', min: {&dollar;min: '&dollar;age'}}}]) 以favorite为_id求favorite相同的人里age最小的
$max 集合中最小值 db.presion.aggregate([{&dollar;group: {_id: '&dollar;favorite', max: {&dollar;max: '&dollar;age'}}}]) 以favorite为_id求favorite相同的人里age最小的
$push 在结果文档中插入值到一个数组中 db.persion.aggregate([{&dollar;group: {_id: '&dollar;favorite', _age: {&dollar;push: '&dollar;age'}}}]) 统计所有favorite相同的人的age存入_age数组中
$addToSet 在结果文档中插入值到一个数组中,但不创建副本 db.persion.aggregate([{&dollar;group: {_id: '&dollar;favorite', _age: {&dollar;addToSet: '&dollar;age'}}}]) 统计所有favorite相同的人的age存入_age数组中,如果_age数组已存在相同的值则不会存入
$first 根据资源文档的排序获取第一个文档数据 db.persion.aggregate([{&dollar;group: {_id: '&dollar;favorite', first_name: {&dollar;first: '&dollar;name'}}}]) 相同favorite中第一个出现的人的name
$last 根据资源文档的排序获取第一个文档数据 db.persion.aggregate([{&dollar;group: {_id: '&dollar;favorite', first_name: {&dollar;last: '&dollar;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" }
>
管道

聚合管道:将当命令前输出的结果作为下一个命令的参数 管道操作可以重复
表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。
常用操作:

  • &dollar;project 修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档
  • &dollar;match 用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作
  • &dollar;limit 用来限制MongoDB聚合管道返回的文档数
  • &dollar;skip 在聚合管道中跳过指定数量的文档,并返回余下的文档
  • &dollar;unwind 将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值
  • &dollar;group 将集合中的文档分组,可用于统计结果
  • &dollar;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 ] }
>

&dollar;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 ] }
>

maikuraki
9 声望0 粉丝