mongo基础

简介

  • MongoDB 是一个基于分布式文件存储的数据库

  • 属于NoSQL数据库,是介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的

  • 旨在为WEB应用提供可扩展的高性能数据存储解决方案

  • 数据结构: 键值对(key-value),类似JSON对象

    {
      name:'Paul',
      age:21,
      gender:'man'
    }
    

基本操作

数据库操作

  • 创建

    use database_name
    

如果数据库存在,则进入指定数据库,否则,创建数据库
此时需要写入数据,数据库才能真正创建成功

  • 查看所有数据库

      show databases | dbs
    
  • 创建集合

      db.createCollection(collection_name)
    
      固定集合
      所谓的固定集合指的是规定集合大小,如果要保存的内容已经超过了集合的长度,那么会采用LRU的算法(最近最少使用原则)将最早的数据移出,从而保存新的数据。
    
      范例:创建一个空集合(固定集合)
      db.createCollection("depts", {"capped": true, "size": 1024, "max": 5})
      其中“capped :true”表示为一个固定集合,而“size:1024”指的是集合所占的空间容量(字节)、“max : 5”最多只能够有五条记录。
    
  • 删除数据库
    先进入要删除的数据库,然后执行命令

      db.dropDatabase()
    
  • 删除集合

      db.collection_name.drop()
    

数据表操作

  •   db.collection_name.insert(document)
    
    • db.collection.find(,)
      query: 查询条件
      projection: 投影操作

    • db.students.find({name:/张/i})
      模糊查询:在进行信息查询的时候,不设置条件永远要比设置条件的查询快很多

    • db.students.count()
      对于集合的数据量而言,在MongoDB里面直接使用count()函数就可以完成了

  • db.collection.updateOne(<query>,<update>) // 更新第一个符合条件的集合
    db.collection.updateMany(<query>,<update>)  // 更新所有符合条件的集合
    
    - query: 查询条件
    - update: 更新的内容
    
  • db.collection_name.deleteOne(<query>) // 删除第一个符合条件的集合
    db.collection_name.deleteMany(<query>) // 删除所有符合条件的集合
    

runCommand

在MongoDB数据库里面,除了一些支持的操作函数之外,还有一个重要的命令:runCommand(),这个函数可以执行所有的特定的MongoDB命令(最底层的函数)。

范例:利用runCommand()实现信息查询
db.shop.runCommand({'geoNear':'shop',near:[10,10],maxDistance:5,num:3})
这类的命令可以说是MongoDB之中最为基础的命令。

消除重复数据
范例:查询所有name的信息
db.students.runCommand({'distinct':'students','key':'name'})
本次的操作没有直接的函数支持,只能够利用runCommand()函数。

数据操作(重点)

数据库的核心——CRUD,增加和删除较为简单,查询和修改较复杂

find

关系运算符

  • $gt 大于

  • $lt 小于

  • $gte 大于等于

  • $lte 小于等于

  • $eq | (key: value) 等于

  • $ne 不等于

先往数据库中添加一些数据

db.students.insert({'name':'张三','sex':'男','age':19,'score': 89,'address': '海淀区'})
db.students.insert({'name':'李四','sex':'女','age':20,'score': 100,'address': '朝阳区'})
db.students.insert({'name':'王五','sex':'男','age':22,'score': 50,'address': '西城区'})
db.students.insert({'name':'赵六','sex':'女','age':21,'score': 60,'address': '东城区'})

exp:

  1. 查询姓名是张三的学生信息

     db.students.find({name:’张三’}).pretty()
    
  2. 查询年龄大于19岁的学生

     db.students.find({age:{$gt:19}}).pretty()
    
  3. 查询成绩大于等于60分的学生

     db.students.find({score:{$gte:60}}).pretty() 
    

逻辑运算符

  • $and

  • $or

  • $not | $nor

exp:

  1. 查询年龄在19 ~ 22岁的学生信息

     db.students.find({age:{$gte:19,$lte:22}}).pretty()
    

逻辑运算中与连接是最容易的,只需要利用,分割多个条件即可

  1. 查询年龄小于20岁,或者成绩大于90分的学生信息

     db.students.find(
     {$or:
         [ 
         {age:{$lt:20}},
         {score:{$gt:90}}
         ]
     }).pretty()
    
  2. 查询年龄大于等于20岁,且成绩小于等于90分的学生信息

     db.students.find(
     {$and:
         [ 
         {age:{$gte:20}},
         {score:{$lte:90}}
         ]
     }).pretty()
    

范围查询

$in: 在范围之中
$nin: 不在范围之中

exp:

  1. 查询姓名是”张三“、”李四、”王五“的学生

     db.students.find({name: {$in:['张三','李四','王五']}}).pret ty()
    
  2. 查询姓名不是”张三“、”李四、”王五“的学生

     db.students.find({name: {$nin:['张三','李四','王五']}}).pretty()
    

数组查询

  • $all

  • $size

  • $slice

  • $elemMatch

首先在数据库中新增一些数据

    db.students.insert({name:'a',sex:'男',age:19,score:89,address:'海淀区',course:['语文','数学','英语','音乐','政治']})
    db.students.insert({name:'b',sex:'男',age:19,score:89,address:'海淀区',course:['语文','数学']})
    db.students.insert({name:'c',sex:'男',age:19,score:89,address:'海淀区',course:['语文','数学','英语']})
    db.students.insert({name:'d',sex:'男',age:19,score:89,address:'海淀区',course:['英语','音乐','政治']})
    db.students.insert({name:'e',sex:'男',age:19,score:89,address:'海淀区',course:['语文','政治']})

$all: 表示全都包括,用法:

    {$all:[内容1,内容2]}

exp:

查询同时参加语文和数学的学生

    db.students.find({course:{$all:['语文','数学']}}).pretty()

数组的操作,可以利用索引,使用key.index的方式来定义索引

查询数组中第二个内容是数学的学生(sh)

    db.students.find({'course.1':'数学'}).pretty()

$size: 控制数组元素数量

exp:

查询只有两门课程的学生

    db.students.find({course:{$size: 2}}).pretty()

$slice: 控制查询结果的返回数量

exp:

查询年龄是19岁的学生,要求之显示两门参加的课程

    db.students.find({age:19},{course:{$slice:2}}).pretty()

此时查询返回的是前两门课程,可以设置参数来取出想要的内容

    $slice:-2   //后两门
    $slice: [1,2]   // 第一个参数表示跳过的数据量,第二个参数表示返回的数据量

嵌套集合运算

对象里面套对象

在数据库中新增数据

    db.students.insert(
    {
        name:'A',sex:'男',age:19,score:89,address:'海淀区',
        course:['语文','数学','英语','音乐','政治'],
        parents:[
            {name:'A(father)',age:50,job:'工人'},
            {name:'A(mother)',age:50,job:'职员'}
        ]
    })
    db.students.insert(
    {
        name:'B',sex:'男',age:19,score:89,address:'海淀区',
        course:['语文','数学'],
        parents:[
            {name:'B(father)',age:50,job:'处长'},
            {name:'B(mother)',age:50,job:'局长'}
        ]
    })
    db.students.insert(
    {
        name:'C',sex:'男',age:19,score:89,address:'海淀区',
        course:['语文','数学','英语'],
        parents:[
            {name:'C(father)',age:50,job:'工人'},
            {name:'C(mother)',age:50,job:'局长'}
            ]
    })

对于嵌套的集合中数据的判断只能通过$elemMatch完成

语法:{ <field>: { $elemMatch: { <query1>, <query2>, ... } } }

exp:

查询父母中有人是局长的信息

    db.students.find({parents: {$elemMatch: {job: '局长'}}}).pretty()

排序

sort({ field: value }) value是1表示升序,-1表示降序

exp:

学生信息按照分数降序排列

    db.students.find().sort({score:-1}).pretty()

分页显示

skip(n): 跳过n条数据

limit(n): 返回n条数据

exp:

  1. 分页显示,第一页,每页显示5条数据

     db.students.find({}).skip(0).limit(5).pretty()
    
  2. 分页显示,第二页,每页显示5条数据

     db.students.find({}).skip(5).limit(5).pretty()
    

判断某个字段是否存在

{$exists:flag} flag为true表示存在,false表示不存在

exp:

  1. 查询具有parents成员的学生

     db.students.find({parents:{$exists: true}}).pretty()
    
  2. 查询不具有course成员的学生

     db.students.find({course: {$exists: false}}).pretty()
    

取模

$mod:[除数,余数]

exp: 查询年龄除以20余1的学生信息

db.students.find({age:{$mod:[20,1]}}).pretty()

update

updateOne() 修改匹配的第一条数据

updateMany() 修改所有匹配的数据

格式:updateOne(<filter>,<update>)

修改器

  • $inc
  • $set
  • $unset
  • $push
  • $addToSet
  • $pop
  • $pull
  • $pullAll
  • $rename

$inc:操作数字字段的数据内容

语法: {"$inc" : {成员 : 内容}}

exp: 将所有年龄为19岁的学生成绩一律减少30分,年龄增加1

    db.students.updateMany({age:19},{$inc:{score:-30,age:1}})

$set:更新内容

语法:{$set: :{属性: 新内容}}

exp: 将20岁学生的成绩修改为89

    db.students.updateMany({age: 20},{$set: {score: 89}})

$unset:删除某个属性及其内容

语法:{$unset: {属性: 1}}

exp:删除张三的年龄和成绩信息

    db.students.updateOne({name:'张三'},{$unset: {age: 1,score: 1}})

$push:向数组中添加数据

语法:{$push: {属性: value}}

exp:在李四的课程中添加语文

    db.students.updateOne({name: '李四'},{$push: {course: '语文'}})

如果需要向数组中添加多个数据,则需要用到$each

exp: 在李四的课程中添加数学、英语

    db.students.updateOne(
        {name:'李四'},
        {$push:
            {
                course:{$each: ['数学','英语']}
            }
        }
    )

$addToSet:向数组里面添加一个新的数据

$push的区别,$push添加的数据可能是重复的,$addToSet只有这个数据不存在时才会添加(去重)

语法:{$addToSet: {属性:value}}

exp:王五新增一门舞蹈课程

    db.students.updateOne(
        {name:'王五'},
        {$addToSet: {course:'舞蹈'}}
    )

$pop:删除数组内的数据

语法:{$pop: {field: value}},value为-1表示删除第一个,value为1表示删除最后一个

exp:删除王五的第一个课程

    db.students.updateOne({name:'王五'},{$pop:{course:-1}})

只是删除属性的内容,属性还在

$pull:从数组中删除一个指定内容的数据

语法:{$pull: {field:value}} 进行数据比对,如果是该数据则删除

exp:删除李四的语文课程

    db.students.updateOne({name: '李四'},{$pull:{course:'语文'}})

$pullAll:一次删除多个数据

语法:{$pullAll:{field:[value1,value2...]}}

exp:删除a的语文数学英语课程

    db.students.updateOne({name:'a'},{$pullAll:{course:['语文','数学','英语']}})

$rename:属性重命名

语法: {$rename: {旧属性名:新属性名}}

exp:把张三的name属性名改为姓名

    db.students.updateOne({name:'张三'},{$rename:{name:'姓名'}})

remove

remove函数是有两个可选项:
·删除条件:满足条件的数据被删除;
·是否只删除一个数据,如果设置为true或者是1表示只删除一个

exp:删除所有姓名里面带有“谷”的信息,默认情况下会全部删除

    db.students.remove({name: /谷/})

范例:删除姓名带有“高”的信息,要求只删除一个

    db.students.remove({name: /高/},true)

游标

所谓的游标就是指的数据可以一行行的进行操作,类似于关系型数据库处理。在MongoDB数据库里面对于游标的控制非常的简 单,只需要使用find()函数就可以返回游标了。对于返回的游标如果要想进行操作,使用两个函数。

hasNext()

next()

相当于每一个数据都单独拿出来进行逐行的控制。当游标数据取出来之后,实际上每行数据返回的都是一个Object型的内容

exp:

    var cursor = db.students.find()
    while(cursor.hasNext()){
    var student = cursor.next()
    print(student.name)
    printjson(student)
    }

索引

简介

在任何的数据库之中,索引都是一种提升数据库检索性能的手段,这一点在MongoDB数据库之中同样是存在的,在MongoDB数据库里面依然会存在有两种的索引创建:是自动创建的,另外一种索引是手工创建的。

exp:重新准备一个新的简单集合

    db.students.drop()
    db.students.insert({'name':'张三','sex':'男','age':19,'score': 89,'address': '海淀区'})
    db.students.insert({'name':'李四','sex':'女','age':20,'score': 100,'address': '朝阳区'})
    db.students.insert({'name':'王五','sex':'男','age':22,'score': 50,'address': '西城区'})

查询默认状态下的students集合的索引内容
db.students.getIndexes()

创建一个索引,在age字段上设置一个降序索引

    db.students.ensureIndex({‘age’:-1})

此时并没有设置索引的名字,所以名字是自动命名的。命名规范:“字段名称_索引的排序模式”。

针对于当前的age字段上的索引做一个分析

    db.students.find({'age':19}).explain()  

此时的查询使用了索引的技术

针对于score字段上设置查询

    db.students.find({score:{$gt:60}}).explain()

此时在score字段上并没有设置索引,所以当前的索引形式就变为了全集合扫描的模式.

复合索引:

    db.students.ensureIndex({age:1,score:-1},{name:'age_1_score_1_index'})

删除一个索引:

    db.students.dropIndex({age:1})

删除全部索引:

    db.students.dropIndexes()

唯一索引

唯一索引的主要目的是用在某一个字段上,使该字段的内容不重复.

创建唯一索引

    db.students.ensureIndex({name:1},{unique:true})

此时若在name中添加重复数据,会报错。

过期索引

在一些程序站点会出现若干秒之后信息被删除的情况,例如:手机信息验证码,在MongoDB里面就可以轻松的实现过期索引,但是这个时间往往不怎么准确。必须要有时间,否则没法实现过期。

设置过期索引

    db.phones.ensureIndex({time:1},{expireAfterSeconds:10})

如果要想实现过期索引,需要保存一个时间信息;

    db.phones.insert({tel:110,code:110,time:new Date()})
    db.phones.insert({tel:111,code:111,time:new Date()})

全文索引

在一些信息管理平台上经常需要进行信息模糊查询,最早的时候是利用了某个字段上实现的模糊查询,但是这个时候返回的信息并不会很准确,因为只能够查A字段或者是B字段,而在MongoDB里面实现了非常简单的全文检索。

定义一个新的集合

    db.news.insert({'title':'gyh',content:'sfq'})
    db.news.insert({'title':'gyh',content:'gry'})
    db.news.insert({'title':'sfq',content:'gry'})

设置全文检索

    db.news.ensureIndex({title:'text',content:'text'})

实现数据的模糊查询
如果要想表示出全文检索,则使用“$text”判断符,而要想进行数据的查询则使用“$search”运算符:

查询单个内容

  db.news.find({$text:{$search:'gry'}})

包含有“gry”与“sfq”的信息

  db.news.find({$text:{$search:'gry gyh'}})

同时包含有“mldn”与“lxh”的内容

    db.news.find({$text:{$search:'\'mldn\' \'lxh\''}})

在进行全文检索操作的时候还可以使用相似度的打分来判断检索成果。

    db.news.find({$text:{$search:'gyh'}},{‘score’:{$meta:'textScore'}})
    db.news.find({$text:{$search:'gyh'}},{‘score’:{$meta:'textScore'}}).sort({'score':{$meta:'textScore'}})

但是在这里面还有一个小问题,如果一个集合的字段太多了,那么每一个字段都分别设置全文检索麻烦点,所以简单一些,可以为所有的字段设置全文检索。
为所有字段设置全文检索

    db.news.ensureIndex({'$**':'text'})

地理信息索引

地理信息索引分为两类:2D平面索引,另外就是2DSphere球面索引。在2D索引里面基本上能够保存的信息都是坐标,而且坐标保存的就是经纬度坐标。

定义一个商铺的集合

    db.shop.insert({loc:[10,10]})
    db.shop.insert({loc:[11,10]})
    db.shop.insert({loc:[10,11]})

为shop的集合定义2D索引
db.shop.ensureIndex({loc:'2d'})

这个时候shop集合就可以实现坐标位置的查询了,而要进行查询有两种查询方式:
·“$near”查询,查询距离某个点最近的坐标点;
·“$geoWithin”查询:查询某个形状内的点;

    db.shop.find({loc:{$near:[11,11]}})

    db.shop.find({loc:{$near:[11,11],$maxDistance:5}})

但是需要注意一点,在2D索引里面虽然支持最大距离,但是不支持最小距离。
但是也可以设置一个查询的范围,使用“$geoWithin”查询,而可以设置的范围:
·矩形范围($box):{"$box":[[x1,y1],[x2,y2]]};
·圆形范围($center):{"$center" : [[x1,y1],r]};
·多边型($polygon):{"$polygon" :[[x1,y1],[x2,y2][x3,y3] , ...]}

查询矩形

    db.shop.find({loc:{$geoWithin:{$box:[[9,9],[12,12]]}}})

查询圆形

     db.shop.find({loc:{$geoWithin:{$center:[[10,10],2]}}})

范例:利用runCommand()实现信息查询

    db.shop.runCommand({'geoNear':'shop',near:[10,10],maxDistance:5,num:3})

这类的命令可以说是MongoDB之中最为基础的命令。

聚合(重点)

MongoDB的产生背景是在大数据环境,所谓的大数据实际上也就是进行的信息收集汇总。那么就必须存在有信息的统计操作,而这样的统计操作就称为聚合

MapReduce功能强大,但是它的复杂度和功能一样强大,那么很多时候我们需要MapReduce的功能,可是又不想把代码写的太复杂,所以从Mongo 2.x版本之后开始引入了聚合框架并且提供了聚合函数:aggregate()。

$group

group主要进行分组的数据操作。

  • $sum

    实现聚合查询的功能——求出每个职位的雇员人数

     db.emps.aggregate([{$group:{_id:'$job',job_count:{$sum:1}}}])
    

    求出每个职位的总工资

     db.emps.aggregate([{$group:{_id:'$job',job_sql:{$sum:'$salary'}}}])
    
  • $avg

    计算出每个职位的平均工资

     db.emps.aggregate([{$group:{_id:'$job',job_avg:{$avg:'$salary'}}}])
    
  • $max/$min

    求出最高与最低工资

      db.emps.aggregate([{$group:{
             _id:'$job',
             job_max:{$min:'$salary'},
             job_min:{$min:'$salary'}
     }}])
    
  • $push

    计算出每个职位的工资数据(数组显示)

     db.emps.aggregate([{$group:
             {_id:'$job',
             job_sal:{$push:'$salary'}}
     }])
    
  • $addToSet

    使用“$push”的确可以将数据变为数组进行保存,但是有一个问题出现了,重复的内容也会进行保存,那么在MongoDB里面提供有取消重复的设置。

      db.emps.aggregate([{$group:
             {_id:'$job',
             job_sal:{$addToSet:'$name'}}
     }])
    
  • $first/$last

    保存第一个/最后一个内容

      db.emps.aggregate([{$group:
             {_id:'$job',
             job_sal:{$first:'$name'}}
     }])
    
      db.emps.aggregate([{$group:
             {_id:'$job',
             job_sal:{$last:'$name'}}
     }])
    

$project(投影)

可以利用“$project”来控制数据列的显示规则,那么可以执行的规则如下:

    |- “_id”列({"_id" : 0 | false}):表示“_id”列是否显示;
    |- 普通列({成员 : 1 | true}):表示要显示的内容;
    |- 条件过滤列({成员 : 表达式}):满足表达式之后的数据可以进行显示。

范例:只显示name、job列,不显示“_id”列

    db.emps.aggregate([
            {$project:{_id:0, name:1, job:1}}
    ])

此时只有设置进去的列才可以被显示出来,而其它的列不能够被显示出来

实际上在进行数据投影的过程里面也支持四则运算:加法(“$add”)、减法(“$subtract”)、乘法(“$multiply”)、除法(“$divide”)、求模($mod)。

范例:观察四则运算

    db.emps.aggregate([
            {$project:{
            _id:0,
            name:1,
            job:1,
            salary:{'年薪':{$multiply:['$salary',12]}}}}
    ])

除了算术运算之外也支持如下的各种运算符:这些操作一般会在$match中去使用,而不是在$project

·关系运算:大小比较(“$cmp”)、等于(“$eq”)、大于(“$gt”)、大于等于(“$gte”)、小于(“$lt”)、小于等于(“$lte”)、不等于(“$ne”)、判断NULL(“$ifNull”),这些返回的结果都是布尔型数据;

·逻辑运算:与(“$and”)、或(“$or”)、非(“$not”);

·字符串操作:连接(“$concat”)、截取(“$substr”)、转小写(“$toLower”)、转大写(“$toUpper”)、不区分大小写比较(“$strcasecmp”)。

范例:查询职位是manager的信息。

    db.emps.aggregate([
            {$project:{
            _id:0,
            name:1,
            '职位':'$job',
            job:{$eq:['$job',’manager’]}}}
    ])

范例:使用字符串截取

     db.emps.aggregate([
            {$project:{
            _id:0,
            name:1,
            '职位':'$job',
            job:{'job名称前三位字符':{$substr:['$job',0,3]}}}}
    ])

$match

“$match”是一个滤波操作,就是进行WHERE的过滤。
这个时候实现的代码严格来讲只是相当于“SELECT * FROM 表 WHERE 条件”,属于所有的内容都进行了查询。

范例:控制投影操作

    db.emps.aggregate([
            {$match:{salary:{$gte:2000,$lte:5000}}},
            {$project:{_id:0,name:1,salary:1}}
    ])

范例:继续分组
db.emps.aggregate([
{$match:{salary:{$gte:1000,$lte:10000}}},
{$project:{_id:0,name:1,job:1,salary:1}},
{$group:{_id:’$job’,count:{$sum:1},avg:{$avg:’$salary’}}}
])

$sort

    db.emps.aggregate([
            {$match:{salary:{$gte:1000,$lte:10000}}},
            {$project:{_id:0,name:1,job:1,salary:1}},
            {$group:{_id:’$job’,count:{$sum:1},avg:{$avg:’$salary’}}},
            {$sort:{count:-1}}
    ])

$limit、$skip

    db.emps.aggregate([
            {$project:{_id:0,name:1,salary:1,job:1}},
            {$skip:3},
            {$limit:5}
    ])

unwind

在查询数据的时候经常会返回数组信息,但是数组并不方便信息的浏览,所以提供有“$unwind”可以将数组数据变为独立的字符串内容。
范例:

    db.depts.insert({title:'技术部',bus:['研发','生产','培训']})
    db.depts.insert({title:'财务',bus:['工资','税收']})

    db.depts.aggregate([
            {$project:{_id:0}},
            {$unwind:'$bus'}
    ])

$geoNear

范例

    db.shop.insert({loc:[10,10]})
    db.shop.insert({loc:[11,10]})
    db.shop.insert({loc:[10,11]})

     db.shop.aggregate([
            {$geoNear:{
            'near':[11,12],
            'distanceField':’loc’,
            'maxDistance':1,
            'num':2,
            'spherical':true}}
    ])

$out

$out”:利用此操作可以将查询结果输出到指定的集合里面。

     db.emps.aggregate([
            {$project:{_id:0}},
            {$out:'emp_infos'}
    ])

其他

MapReduce

MapReduce是整个大数据的精髓所在(实际中别用),所谓的MapReduce就是分为两步处理数据:

· Map:将数据分别取出;

· Reduce:负责数据的最后的处理。

可是要想在MongoDB里面实现MapReduce处理,那么复杂度是相当高的。

范例:建立一组雇员数据

    db.emps.insert({name:'zhangsan',age:30,sex:'man',job:'ClERK',salary:1000})
    db.emps.insert({name:'lisi',age:28,sex:'woman',job:'ClERK',salary:5000})
    db.emps.insert({name:'wangwu',age:26,sex:'man',job:'MANAGER',salary:6000})
    db.emps.insert({name:'zhaoliu',age:32,sex:'woman',job:'MANAGER',salary:7000})
    db.emps.insert({name:'sunqi',age:31,sex:'man',job:'ClERK',salary:2000})
    db.emps.insert({name:'wangba',age:35,sex:'woman',job:'PRESIDENT',salary:9000})

使用MapReduce操作最终会将处理结果保存在一个单独的集合里面,而最终的处理效果如下。

范例:按照职位分组,取得每个职位的人名
·编写分组的定义:

    var jobMapFun = function(){
            emit(this.job,this.name)
    }

第一组:{key:’CLERK’,values:[姓名,姓名...]}

·第二步:编写reduce操作;

    var jobReduceFun = function(key,values){
            return {job:key,names:values}
    }

·第三步:针对于MapReduce处理完成的数据实际上也可以执行一个最后处理。

     var jobFinalizeFun = function(key,values) {
            if(key === 'PRESIDENT'){
                    return {job:key,names:values,info:'the boss'}
            }
            return {job:key,names:values}
    }

·进行操作的整合:
db.runCommand({
mapreduce:'emps',
map:jobMapFun,
reduce:jobReduceFun,
out:’t_job_emp’,
finalize:jobFinalizeFun
})

现在执行之后,所有的处理结果都保存在了“t_job_emp”集合里面。
  db.t_job_emp.find().pretty()

范例:统计出各性别的人数、平均工资、最低工资、雇员姓名

    var sexMapFun = function(){
            // 定义好分组的条件,以及每个集合要取出的内容
            emit(this.sex,{ccount:1,csal:this.salary,cmax:this.salary,cmin:this.salary,cname:this.name})
    }

    var sexReduceFun = function(key,values){
            var total = 0      //统计
            var sum = 0      // 计算总工资
            var max = values[0]    //假设第一个数据是最高工资
            var min = values[0]    //假设第一个数据是最低工资
            var names = new Array()   //定义数组内容
            for(var x in values) {    // 表示循环取出里面的内容
                    total += values[x].ccount // 人数增加
                    sum += values[x].csal     // 循环取出所有的工资,并且累加
                    if(max < values[x]){
                            max = values[x]
                    }
                    if(min > values[x]){
                            min = values[x]
                    }
                    names[x] = values[x].cname  // 保存姓名
            }
            var avg = (sum/total).toFixed(2)
            // 返回数据的处理结果
            return {count:total,avg:avg,sum:sum,max:max,min:min,names:names}
    }

    db.runCommand({
    mapreduce:'emps',
    map:sexMapFun,
    reduce:sexReduceFun,
    out:'t_sex_emp'
    })
 
    **虽然大数据的时代提供有最强悍的MapReduce支持,但是从现实的开发来讲,真的不可能使用起来.**

mongofiles

在MongoDB里面支持大数据的存储(例如:图片、音乐、各种二进制数据),但是这个做法需要用户自己进行处理了,使用“mogofiles”命令完成。

1、 利用命令行进入到所在的路径下;
2、 mongofiles --port=27001 put photo.tif
3、 查看保存的文件;
mongofiles --port=27001 list
4、 MongoDB里面有一个fs系统集合,这个集合默认保存在了test数据库下
use test;
db.fs.files.find()
5、删除文件
mongofiles --port=27001 delete photo.tif

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×