zoukankan      html  css  js  c++  java
  • python 操作mongodb

    以前搞过python和mongodb,时间长了 就忘了, 并且每次找百度也不是特别方便, 今天就此整理一下。首先来看最基础的

    CRUD操作

    from pymongo import MongoClient 
     
    #创建连接
    conn =  MongoClient("mongodb://root:root@127.0.0.1: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()

    索引操作

    from pymongo import MongoClient 
     
    #创建连接
    conn = MongoClient("mongodb://root:root@127.0.0.1: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()

    以二进制的形式 读写文件(以图片为例)

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

    借用GridFS来处理文件

    from pymongo import MongoClient
    from gridfs import *
     
    conn = MongoClient("mongodb://root:root@127.0.0.1:27017/")
    db = conn.image 
     
    #存储
    f = open('/root/test.jpg','rb')
    #创建写入流
    imgput = GridFS(db)
    #将数据写入,文件类型和名称通过前面的分割得到
    insertimg=imgput.put(f,content_type='jpg',filename='/root/test.jpg')
    f.close()
    #创建成功后,会在集合中生成fs.flies和fs.chunks
     
    gridFS = GridFS(db, collection="fs")
    for grid_out in gridFS.find():
        data = grid_out.read() # 获取图片数据
        outf = open('/root/test3.jpg','wb')#创建文件
        outf.write(data)  # 存储图片
        outf.close()
     
    conn.close()

    有关GridFS的描述:

    一、概述

        GridFS是基于mongodb存储引擎是实现的“分布式文件系统”,底层基于mongodb存储机制,和其他本地文件系统相比,它具备大数据存储的多个优点。GridFS适合存储超过16MB的大型文件,不过16M数据在当今互联网时代,已经不足为奇。我们可以使用GridFS构建大规模的“图片服务器”、“文档服务器”、“视频、音频”文件服务器,GridFS对于web应用,可以结合nginx插件“ningx-gridfs”能够简单的实现负载均衡等特性,非常便捷;可以简单认为GridFS是为web应用而生。个人认为,目前架构比较简单的NoSQL文件系统中GridFS是最优秀的。

        GridFS并不是将单个文件直接存储为一个document,而是将文件分成多个parts或者说chunks,然后将每个chunk作为作为一个单独的document存储,然后将chunks有序保存。默认情况下,GridFS的chunk大小位255k。GridFS使用2个collections来存储这些文件,一个collection存储文件的chunks(实际文件数据),另一个则存储文件的metadata(用户自定义的属性,filename,content-type等)。

        当用户查询GridFS中的文件时,客户端或者driver将会重新按序组装这些chunks。用户可以range查询文件,也可以获取文件的任意部分的信息,比如:跳过(skip)视频或者音频(任何文件)的中间部,实现“range access of single file”。

        对于mongodb而言,每个document最大尺寸为16M,如果想存储一条数据(比如一个文件)超过16M,那么只能使用GridFS支持;GridFS可以支持单个文件尺寸达到数G,读取文件时可以分段读取。此外,GridFS可以从Mongodb的高性能、高可用特性中获益,比如我们可以在“replica set”或者“sharding”架构模式下使用GridFS。

    二、使用场景

        document的大小超过16M是使用GridFS的条件之一,因为mongodb普通的collection无法支持16M以上的document,我们不得不选择其他方案;在一些情况下,将这些大文件存储在GridFS中,比直接存储在本地文件系统中更加适合:

        1)如果你的文件系统对每个目录下文件的个数有限制(或者太多,将会影响文件的打开速度等)。

        2)如果你的文件数据,有分数据中心镜像保存(大数据情况,可用性保证)。

        3)如果你希望访问一个超大的文件,而不希望将它全部加入内存,而是有“range access”的情况,即分段读取,那么GridFS天生就具备这种能力,你可以随意访问任意片段。

        对于一个大文件,如果你希望原子性的更新它的全部内容,那么GridFS将不适合;比如同时更新一个文件的多个chunk,因为mongodb本身没有事务机制。

        对于小于16M的文件,比如一些图片、CSS、js文件等,应该将它们直接存储在普通的collection中而非GridFS(bindata,参见org.bson.types.Binary),因为它们通常较小,GridFS无法发挥其优势。当然,你为了统一application的“文件系统”存储方式,也可以将这些小文件保存在GridFS中,性能也不会差的太多,为了提升性能,对这些小文件,可以在存储时手动设置它的chunkSize,避免文件被切分成多个chunks来提高性能。

  • 相关阅读:
    jquery ajax
    对话:工作时常用的借口
    asp.net 加页面Loading效果
    (转)row_number( )、rank( )、,DENSE_RANK( )、ntile( )
    商务英语:出差用语
    怎样工作才能收入更多
    上班族下午如何才不瞌睡?
    (转)系统权限大致分类
    对话:办公室午餐时间
    如何建立一个“铁打的营盘”?
  • 原文地址:https://www.cnblogs.com/majiang/p/11171599.html
Copyright © 2011-2022 走看看