MongoDB day04

 

目录

聚合操作

聚合管道

文件存储

mongodb存储文件本身

游标

通过python操作MongoDB


day04

聚合操作

  1. 对文档的信息进行整理统计的操作
    返回:统计后的文档集合
  2. 格式:db.collection.aggregate()
    1. 功能:聚合函数,完成聚合操作
    2. 参数:聚合条件,配合聚合操作符使用
    3. 返回:聚合后的结果
  3. 聚合操作符
  4. $group 分组聚合  (及其它聚合操作)要配合具体的统计操作符获取结果

操作符含义例子
$sum求和

e.g.求男女生各多少人:

db.class2.aggregate({$group:{_id:'$gender',num:{$sum:1}}})

$group:分组,_id:'$gender':按照gender统计,num:{$sum:1}:统计结果,求和每有一个加1

e.g.统计所有男生和女生年龄之和:

db.class2.aggregate({$group:{_id:'$gender',num:{$sum:'$age'}}})

$avg求平均

e.g.求男生 女生年龄的平均数:

db.class2.aggregate({$group:{_id:'$gender',num:{$avg:'$age'}}})

$max求最大值

e.g.求男生女生年龄的最大值:

db.class2.aggregate({$group:{_id:'$gender',num:{$max:'$age'}}})

$min求最小值

e.g.求男生女生年龄的最小值:

db.class2.aggregate({$group:{_id:'$gender',num:{$min:'$age'}}})

$project用于修改文档的展示效果

e.g.$project值的用法同find()

db.class2.aggregate({$project:{_id:0,name:1,age:1}})

e.g.自定义显示的域名

db.class2.aggregate({$project:{_id:0,Name:'$name',Age:'$age'}})

 

$match过滤想要的数据

e.g.过滤年龄大于30的数据,$match值的写法同query

db.class2.aggregate({$match:{age:{$ge:30}}})

$limit显示前几个文档

e.g.显示前3条

db.class2.aggregate({$limit:3})

$skip跳过前几个文档显示

e.g.跳过前2条

db.class2.aggregate({$skip:2})

$sort排序

e.g.按年龄升序排序

db.class2.aggregate({$sort:{age:1}})

聚合管道

  1. 将前一个聚合操作产生的结果,交给后一个聚合操作继续使用叫聚合管道
  2. 格式:db.collection.aggregate([{聚合1},{聚合2},{}...])
  3. e.g.  $match -->$sort -->$project
    db.class1.aggregate([{$match:{gender:'m'}},{$sort:{age:1}},{$project:{_id:0}}])
  4. 聚合练习,使用grade数据库
    1. 给更多同学添加 内部文档
      score:{english:87,chines:76,math:91}
      db.class1.update({},{score:{english:87,chines:76,math:91}})
    2. 按照性别统计每组人数
      db.class1.aggregate({$group:{_id:'$sex',num:{$sum:1}}})
    3. 统计该班中有哪个同学姓名为重名同学
      db.class1.aggregate([{$group:{_id:'$name',num:{$sum:1}}},{$match:{num:{$gt:1}}}])
    4. 统计所有男生的语文成绩,只打印姓名,性别,语文成绩即可
      db.class1.aggregate({$match:{sex:'m'}},{$project:{_id:0,name:1,sex:1,'score.chinese':1}})
    5. 将所有女生按照英语成绩降序排序
      db.class1.aggregate([{$match:{sex:''w}},{$sort:{'score.english':-1}}])

文件存储

  1. 存储路径
    将文件放在本地路径(网络路径)下,然后数据库中存储该文件的查找路径

    优点:节省数据库空间
    缺点:当数据或者文件位置发生变化时文件即丢失
  2. 将文件转换为二进制,存储文件本身
    数据库支持二进制数据格式
    将文件转换为二进制格式,然后存入数据库中

    优点:数据库和文件绑定,数据库在文件即在
    缺点:占用数据库空间大,存取效率低

mongodb存储文件本身

  1. 前提条件:

    1. 如果是小文件建议转换二进制直接插入
    2. 如果是大文件建议使用GridFS方案存储 >16m
  2. GridFS方案解释
    1. 在mongodb一个数据库中使用两个集合配合存储文件
    2. fs.files 用来存储文件的相关信息,为每一个文件创建一个文档,存储文件名,文件大小,存入时间。。。
    3. fs.chunks用来分块存储文件的实际内容
                          Binary data 类型数据
  3. 存储方法
    mongofiles  -d  dbname   put   file
                    数据库       要存储的文件
    注意:如果数据库不存在自动创建数据库
         数据库中会自动创建fs.files  fs.chunks两个集合
    fs.files文档结构
    { "_id" : ObjectId("5b7cdcd769d72e12b4f166d0"), "chunkSize" : 261120, "uploadDate" : ISODate("2018-08-22T03:47:35.381Z"), "length" : 305033, "md5" : "3698b5e762b5b396766aaf9feef7e10d", "filename" : "file.jpg" }
    
    
    fs.chunks文档结构
    
    { "_id" : ObjectId("5b7cdcd769d72e12b4f166d2"), "files_id" : ObjectId("5b7cdcd769d72e12b4f166d0"), "n" : 1, "data" : BinData(0,"tQWR0AR......AG") }
    
    * 同一个文件fs.files中的_id值等于fs.chunks中的    files_id域的值

     

  4. 提取方法

    1. 格式:mongofiles -d dbname get file
    2. GridFS的优缺点 
      优点 : 存储方便,提供较好的命令支持 和编程接口
      缺点 : 存取效率低

 

 

游标

mongo shell中获取游标

  • mongo shell 下支持JS代码,可以通过JS获取游标,进而获取数据操作结果

  • e.g.

  1. var cursor = db.class1.find()
  2. cursor.next() 获取下一条结果
  3. cursor.hasNext() 查看是否有下一个对象

通过python操作MongoDB

  •   pymongo模块  第三方模块
  • 安装
    sudo pip3 install pymongo
  1. 操作步骤
    1. 连接数据库,生成数据库连接对象
      conn = pymongo.MongoClient('localhost',27017)
    2. 选择要操作的数据库,生成数据库对象(__setitem__)
      db = conn.stu
      或者db = conn['stu']
    3. 获取集合对象
      myset = db.class0
      或者myset = db['class0']
    4. 通过集合对象调用mongodb数据库操作函数,增删改查,聚合,索引...
    5. 关闭数据库连接
      conn.close()
  2. 插入文档
    1. insert()  插入数据 功能同mongoshell
    2. insert_many()  插入多条
    3. insert_one()  插入一条
    4. save()  插入数据,通过_id可以修改
  3. 查找操作
    1. find()
      功能:对数据库进行查找
      参数:同mongoshell find()
      返回值:返回游标对象

    2. cursor 属性函数
      limit()
      skip()
      count()
      sort()
      pymongo:sort([('age',1),('name',1)])
      mongoshell:sort({age:-1,name:1})
      next()
      如果通过for 或者next操作了游标对象,在调用limit,skip,sort会报错
    3. find_one()
      用法同mongoshell中findOne()
      返回一个字典
  4. 修改操作
    1. update(query,updata,upsert=False,multi=False)
    2. update_many()  修改多个 
    3. update_one()   修改一个
  5. 删除操作
    1. remove(query,multi = True)
      功能:删除文档
      参数:query 筛选条件
      multi:
      默认True表示删除所有符合条件的
      False只删除一条
  6. 复合功能函数
    find_one_and_delete() 查找并删除
    from pymongo import MongoClient 
    
    #创建连接
    conn = MongoClient('localhost',27017)
    
    #创建数据库对象
    db = conn.stu 
    
    #创建集合对象
    myset = db.class4 
    
    # print(dir(myset))
    
    #插入操作
    # myset.insert({'name':'张铁林','King':'乾隆'})
    # myset.insert([{'name':'张国立','King':'康熙'},\
    #     {'name':'陈道明','King':'康熙'}])
    # myset.insert_many([{'name':'唐国强','King':'雍正'},\
    #     {'name':'陈建斌','King':'雍正'}])
    # myset.insert_one({'name':'郑少秋','King':'乾隆'})
    # myset.save({'_id':1,'name':'聂远','King':'乾隆'}) 
    
    #查找操作
    
    # cursor = myset.find({},{'_id':0})
    
    #i为每个文档对应的字典
    # for i in cursor:
    #     print(i['name'],'--->',i['King'])
    
    # myset = db.class1 
    #操作符使用引号变为字符串
    # cursor = myset.find({'age':{'$gt':30}},{'_id':0})
    
    # cursor.limit(2)#获取前两个文档
    # cursor.skip(2) #跳过前两个
    # cursor.sort([('age',-1),('name',1)]) #对游标内容排序
    
    # for i in cursor:
    #     print(i)
    # print(cursor.next()) #获取下一个文档
    
    
    # dic = {'$or':[{'age':{'$gt':35}},{'gender':'w'}]}
    # data = myset.find_one(dic,{'_id':0})
    # print(data)
    
    #修改操作
    # myset.update({'name':'张国立'},\
    #     {'$set':{'king_name':'玄烨'}})
    
    # myset.update({'name':'霍建华'},{'$set':{'King':'乾隆'}},\
    #     upsert = True)
    
    # myset.update({'King':'乾隆'},\
    #     {'$set':{'king_name':'弘历'}},multi = True)
    
    # myset.update_one({'King':'康熙'},\
    #     {'$set':{'king_name':'爱新觉罗玄烨'}})
    
    # myset.update_many({'King':'雍正'},\
    #     {'$set':{'king_name':'胤禛'}})
    
    #删除操作
    
    # myset.remove({'King':'康熙'})
    # myset.remove({'King':'乾隆'},multi = False)
    
    #查找并删除
    print(myset.find_one_and_delete({'King':'乾隆'}))
    
    
    #关闭连接
    conn.close()

  7. 索引操作
    1. ensure_index() 创建索引
    2. list_indexes() 查看索引
    3. drop_index() 删除一个索引
    4. drop_indexes() 删除所有索引
  8. 聚合操作
    1. 格式:aggregate([])
      参数和mongoshell一样
      返回值和find() 函数一样也是得到一个游标对象
      from pymongo import MongoClient 
      
      #创建连接
      conn = MongoClient('localhost',27017)
      
      #创建数据库对象
      db = conn['stu'] 
      
      myset = db['class1'] 
      
      #删除所有索引
      # myset.drop_indexes()
      
      #创建索引
      # index = myset.ensure_index('name')
      #创建复合索引
      # index = myset.ensure_index([('name',-1),('age',1)])
      # print(index)
      
      #删除一个索引
      # myset.drop_index('name_1')
      
      #创建特殊索引
      # index = myset.ensure_index('name',name = "myIndex",\
      #     unique = True,sparse = True)
      
      #查看集合中的索引
      # for i in myset.list_indexes():
      #     print(i)
      
      myset = db.class4 
      
      l = [
          {'$group':{'_id':'$King','num':{'$sum':1}}},
          {'$match':{'num':{'$gt':1}}}
      ]
      
      cursor = myset.aggregate(l)
      for i in cursor:
          print(i)
      
      conn.close()

       

  9. pymongo进行文件存取操作
    GridFS 文件提取
    import gridfs
    1. 连接数据库,获取相应的数据库对象
    2. 通过gridfs.GridFS(db) 获取集合对象 (代表存储文件的两个集合)
    3. 通过find() 查找文件返回游标
    4. 通过循环遍历游标获取指定文件对象,read()读取文件内容写入本地
      from pymongo import MongoClient 
      #pymongo绑定的模块
      import gridfs
      
      conn = MongoClient('localhost',27017)
      db = conn.grid 
      
      #获取gridfs对象
      #fs综合了fs.files  fs.chunks两个集合的属性内容
      fs = gridfs.GridFS(db)
      
      #查文档生产游标
      files = fs.find()
      
      #获取每一个文件的对象
      for file in files:
          print(file.filename)
          if file.filename == 'file.jpg':
              with open(file.filename,'wb') as f:
                  #从数据库读取出来
                  data = file.read()
                  #写入本地
                  f.write(data)
      
      conn.close()

       

  10. 以二进制的方式存取文件
    import bson.binary
    from pymongo import MongoClient 
    import bson.binary 
    
    conn = MongoClient('localhost',27017)
    db = conn.images 
    myset = db.img 
    
    #存储
    # f = open('file.jpg','rb')
    
    # #转换为mongodb的二进制数据存储形式
    # content = bson.binary.Binary(f.read())
    
    # #插入到数据库
    # myset.insert({'filename':'file.jpg','data':content})
    
    #提取
    
    data = myset.find_one({'filename':'file.jpg'})
    
    #通过字典获取到数据库内容写入本地
    with open(data['filename'],'wb') as f:
        f.write(data['data'])
    
    conn.close()

     

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值