MongoDB使用

作者: maikuraki | 来源:发表于2018-01-28 19:37 被阅读303次

    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({$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 ] }
    >
    

    相关文章

      网友评论

        本文标题:MongoDB使用

        本文链接:https://www.haomeiwen.com/subject/nemzaxtx.html