(三)MongoDB高级操作

MongoDB高级操作

.MongoDB的权限管理

  • 为什么要设置权限管理
    刚安装完毕的mongodb默认不适用权限认证方式启动,然而公网运行系统需要设置权限以保证数据安全

  • MongoDB的权限管理方案
    ①mongodb没有默认管理员账号,需要添加管理员账号,开启验证
    ②用户只能在用户所在的数据库登录
    ③管理员账号可以管理所有数据库

  • 开启权限认证的方式
    权限认证默认是关闭的

    ①在启动数据库的时候添加--auth参数
    sudo mongod --auth

    ②在配置文件中添加auth = true,然后加载配置文件启动

mongodb创建用户

所有的用户都必须使用管理员账户创建

use admin           创建管理员用户使用的数据库

选择数据库后使用相应方法创建用户及权限

db.createUser({
        user:”用户名”,
        pwd:”密码”,
        roles:[{role:”权限”,db:”数据库”}]
    })
    
    roles为权限设置的文档,文档中db为指定的数据库, role为权限(最常用的为root,read,readWrite)

mongodb创建用户

查看已经创建的用户权限

show users
    
use admin
db.system.users.find()

数据库权限的认证

use dbname
db.auth(user,pwd)

删除某一用户及权限

db.dropUser(用户名)

MongoDB的聚合运算

为什么要进行聚合运算

  • 传统的查询运算知识将符合条件的数据放到结果集中,而聚合运算则将数据聚合到一起,然后通过管道做后续操作
    如何进行聚合运算

  • 实现聚合运算的方法� db.colname.aggregate([ {管道 : {表达式}} ])

聚合运算是与管道配合使用的,管道是可以有多种的,聚合之后的数据会依次经过管道

  • 常见管道
 $match 
    ①$match实现在聚合中进行查找操作,实现的功能同find()
    ②与find()操作的区别在与查询结果可以进行后续操作,而find不可以
    
    db.colname.aggregate({$match:{key:{$gt:n}}})
    查找key的值大于n的数据,前面的运算符在这里都可以使用

$project

功能类似于查询之后的投影操作
    db.colname.aggregate(
        {$match:{key:{$gt:n}}},
        {$project:{_id:0}}
    )
    使用match进行比对过滤之后的结果经过project进行字段筛选之后再输出出来

$limit

①功能同查询之后的limit操作,返回规定的数据量
    
    db.colname.aggregate(
        {$match:{key:{$gt:n}}},
        {$limit:n}
    )

$skip

跳过指定数量的文档
    
    db.colname.aggregate(
        {$match:{key:{$gt:n}}},
        {$skip:n}
    )
    在这里需要注意的是skip与limit的配合使用与find中是不同的,管道是依次执行的,需要根据业务需要进行配置

$sort

功能通find的排序操作,对数据进行排序
    
    db.colname.aggregate(
        {$match:{key:{$gt:n}}},
        {$sort:{key1:1,key2:-1}}
    )

$unwind

拆分字段值为列表的字段
    db.colname.aggregate(
        {$match:{key:{$gt:n}}},
        {$unwind:”$key”}
    )
    不包含该字段的数据

MongoDB的索引

  • 为什么要使用索引
    索引可以提升查询速度,提升数据库查询的性能

  • 索引的优点点与缺点:
    优点:
    提高数据的查询速度
    缺点:
    牺牲了数据库的插入和更新速度

  • 如何查看语句执行情况

在执行语句之后追加explain(),并且提供参数executionStats
db.colname.find(query).explain(‘executionStats’)

索引的相关操作

查看已存在的索引

db.colname.getIndexes()

创建索引

    索引创建的通用规则:
    ①创建索引使用的文档中键为设置索引的字段,值为1表示索引按照升序存储,值为-1则表示索引按照降序存储
        ②当有大量数据时,创建索引会非常缓慢,因此可以后台创建索引,在创建索引的时候添加{background:true}
单一索引

db.colname.ensureIndex({key:1},{background:true})


联合索引

db.colname.ensureIndex({key1:1,key2:1}
创建联合索引之后,可以使用key1或者key1,key2的查询进行查找
唯一索引
              db.colname.ensureIndex({key:1},{“unique”:true})

          注意事项:
          ①当创建一个key为唯一索引时,新插入的数据如果key的值与已存在的数据相同,则会报错。

          ②当对已存在数据的集合创建唯一索引时,可能会因为重复,导致创建不成功,使用dropDups可以删除重复文档,但是我们一般不建议使用
        db.colname.ensureIndex({key:1},{“unique”:true,”dropDups”:true})

查询时强制使用索引

db.colname.find({key1:value}).hint(索引文档)

删除索引

db.colname.dropIndex({key:1})

查询优化器

单索引
当查询的key正好为设置的索引的时候,优化器直接使用索引

复合索引
①当有若干个索引能适合查询用到的key时,优化器会同时并行使用索引进行查询,选择最快索引
②优化器会定期或定查询次数重新进行最有索引的筛选

索引与全表扫描的对比选择

MongoDB的备份与恢复

数据的备份

为什么进行数据备份?
数据备份指的是将数据备份到指定的目录,并在需要的时候进行恢复,一般用于灾难处理

  • 如何进行数据备份?
    mongodump -h host -d dbname -o directionary
    将指定的数据库备份到指定的目录中

  • 如何进行数据恢复?
    mongorestore -h host -d dbname --dir directionary
    数据的导出与导入

为什么进行数据的导出遇导入?

数据库中的数据在与其他平台和应用进行交互时需要按照指定格式导出交给后续步骤进行处理

  • 如何进行数据备份?
    mongoexport -d dbname -c colname -type json/csv –f file1,file2,file… -o filename
    将指定的结合中的数据导出成文件

  • 如何进行数据导入?
    mongoimport -d dbname -c colname filename

Python与MongoDB的交互



MongoDB的ORM

安装



安装成功后,可以测试。


如何连接数据库


连接本地的数据库用第一个方式就可以啦。
先启动MongoDB服务,然后连接,

import mongoengine
from mongoengine import connect
connect(‘students’)

ORM 模型的介绍



from mongoengine import connect,Document,EmbeddedDocument,\
        StringField,IntField,FloatField,ListField,EmbeddedDocumentField

connect('students')

SEX_CHOICES = (
    ('male','男'),
    ('female','女'),
)

class Grade(EmbeddedDocument):
    ''' 成绩 '''
    name = StringField(required=True)
    score = FloatField(required=True)
    # 最后要把它关联进去

class Student(Document):
    name = StringField(max_length=32,required=True)
    age = IntField(required=True)
    sex = StringField(choices=SEX_CHOICES,required=True)
    grade = FloatField()
    address = StringField()
    # 下面需要声明一个分数,由于有科目所以string类型搞不定
    # 嵌套一个
    grades = ListField(EmbeddedDocumentField(Grade))

新增数据

从上图可以看出可以通过变动的DynamicDocument 活动的文档来添加属性。

查询数据



减号代表倒序排列。
以年龄排序,使用get获取数据,发现多条数据



报错,是三条数据,所以错啦。

也可以重新制定排序


修改、删除数据


通过修改器,两个下划线。


大于16年龄
完整的代码:

from mongoengine import connect,Document,EmbeddedDocument,\
        StringField,IntField,FloatField,ListField,EmbeddedDocumentField,DynamicDocument

connect('students')

SEX_CHOICES = (
    ('male','男'),
    ('female','女'),
)

class Grade(EmbeddedDocument):
    ''' 成绩 '''
    name = StringField(required=True)
    score = FloatField(required=True)
    # 最后要把它关联进去

class Student(DynamicDocument):
    name = StringField(max_length=32,required=True)
    age = IntField(required=True)
    sex = StringField(choices=SEX_CHOICES,required=True)
    grade = FloatField()
    address = StringField()
    # 下面需要声明一个分数,由于有科目所以string类型搞不定
    # 嵌套一个
    grades = ListField(EmbeddedDocumentField(Grade))
    #remark = StringField()

    #这里不指定连接数据表名,根据类名自动创建
    meta = {
        'collection':'students',
        'ordering':['-age']
    }


class TestMongoEngine(object):

    def add_one(self):
        ''' 添加一条数据到数据库 '''
        yuwen = Grade(
            name = '语文',
            score = 90)
        shuxue = Grade(
            name = '数学',
            score = 100)
        stu_obj = Student(
            name='张三5',
            # 年龄是必须填写的,不填写报错
            age = 17,
            sex = 'male',
            grades = [yuwen,shuxue]
        )
        stu_obj.remark = 'ramark'
        stu_obj.save()
        return stu_obj

    def get_one(self):
        '''查询一条数据'''
        return Student.objects.first()

    def get_more(self):
        '''查询多条数据'''
        return Student.objects.all()

    def get_from_id(self,oid):
        '''根据id查询数据'''
        # z这里也可以用get
        return Student.objects.filter(pk=oid).first()

    def update(self):
        '''修改数据'''
        # 修改所有的男生年龄,增加10岁
        #return Student.objects.filter(sex='male').update(inc__age = 10)
        # 修改一条数据
        return Student.objects.filter(sex='male').update_one(inc__age=100)

    def delete(self):
        '''删除数据 '''
        # 删除一条数据
        #return Student.objects.filter(sex='male').first().delete()
        # 删除多条数据
        return Student.objects.filter(sex='male').delete()



def main():
    obj = TestMongoEngine()
    # rest = obj.add_one()
    # print(rest.pk)

    # 返回的是对像
    # rest = obj.get_one()
    # print(rest.id)
    # print(rest.name)

    # rows = obj.get_more()
    # for row in rows:
    #     print(row.name)


    # rest = obj.get_from_id('5b272b2dbb07651ad02a143e')
    # if rest:
    #     print(rest.id)
    #     print(rest.name)

    # rest = obj.update()
    # print(rest)  # 打印的行数 3

    rest = obj.delete()
    print(rest)  # 打印的行数 3

if __name__ == '__main__':
    main()

网易新闻实战


依赖安装

更多详情请点击官网http://flask-mongoengine.readthedocs.io/en/latest/

新闻前台



然后,新闻的模型,连接数据库。
通过flask-mongoengine



在MongoDB数据库中插入一些新的数据,

切换到mongo_news数据库,




下面定义模型,新闻,图片是准备好的。


还有一些评论,可以做些扩展,类似学生的分数。
最后制定collection

下面做前台的展现,首先引入





上面的要修改一下,否则页面的内容都是一样的


前台



新闻数据的分页




最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,843评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,538评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,187评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,264评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,289评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,231评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,116评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,945评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,367评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,581评论 2 333
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,754评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,458评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,068评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,692评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,842评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,797评论 2 369
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,654评论 2 354

推荐阅读更多精彩内容

  • MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写,旨在为 WEB 应用提供可扩展的高性能数据...
    LittlePy阅读 1,561评论 0 4
  • 什么是Mongodb数据库? MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统 Mo...
    瘦不下去了阅读 669评论 0 0
  • 1. MongoDB 简介 MongoDB是一个可扩展的高性能,开源,模式自由,面向文档的NoSQL,基于分布式文...
    rhlp阅读 1,113评论 0 3
  • 简介 MongoDB 是一个基于分布式文件存储的NoSQL数据库 由C++语言编写,运行稳定,性能高 旨在为 WE...
    大熊_7d48阅读 36,830评论 1 9
  • 天下黄河第一湾 扎尕那,一座天然石城,藏语意为石匣子。 色达佛学院,红色小木屋绵延起伏。 年宝玉则,这里流传着一个...
    左耳情深阅读 178评论 0 2