MongoDB快速入门

作者: f050d162bcc1 | 来源:发表于2018-10-07 19:37 被阅读19次
    mangodb

    一、mongodb的介绍

    1、nosql的介绍

    • "NoSQL"⼀词最早于1998年被⽤于⼀个轻量级的关系数据库的名字
    • 随着web2.0的快速发展, NoSQL概念在2009年被提了出来
    • NoSQL在2010年⻛⽣⽔起, 现在国内外众多⼤⼩⽹站, 如facebook、 google、 淘宝、 京东、 百度等, 都在使⽤nosql开发⾼性能的产品
    • 对于⼀名程序员来讲, 使⽤nosql已经成为⼀条必备技能
    • NoSQL最常⻅的解释是“non-relational”, “Not Only SQL”也被很多⼈接受, 指的是⾮关系型的数据库

    2、关系和非关系型的介绍

    不管我们学习什么数据库都应该学习其中的基础概念,在mongodb中基本的概念是 <b style='color:red'>文档、集合、数据库</b>

    SQL概念 MongoDB概念 说明
    database database 数据库
    table collection <b>数据库表/集合
    row document <b>数据记录行/文档
    column field 数据字段/域
    index index 索引
    table joins 表连接mongoDB不支持
    primary key primary key 主键,MongoDB自动将_id设置为主键
    • 通过图示我们也可以更加直观的了解Mongo中的一些概念
    20180924_11

    关系数据库很强⼤,但是它并不能很好的应付所有的应⽤场景。 MySQL的扩展性差,⼤数据下IO压⼒⼤, 表结构更改困难

    3、mongdb的优势

    优势 说明
    易扩展 NoSQL数据库种类繁多,但是⼀个共同的特点都是去掉关系数据库的关系型特性.数据之间⽆关系,这样就⾮常容易扩展
    大数据量,高性能 NoSQL数据库都具有⾮常⾼的读写性能,尤其在⼤数据量下,同样表现优秀.这得益于它的⽆关系性,数据库的结构简单
    灵活的数据模型 NoSQL⽆需事先为要存储的数据建⽴字段,随时可以存储⾃定义的数据格式.⽽在关系数据库⾥,增删字段是⼀件⾮常麻烦的事情.如果是⾮常⼤数据量的表,增加字段简直就是⼀个噩梦

    二、mongodb安装

    sudo apt-get install  mongodb 
    

    三、mongodb基本命令

    1. 常用基本命令

    功能 命令
    启动 sudo service mongod start
    停止 sudo service mongod stop
    重启 sudo service mongod restart
    查看是否启动成功 ps ajx | grep mongod
    配置文件的位置 /etc/mongod.conf
    默认端口 27017
    日志的位置 /var/log/mongodb/mongod.log
    启动本地客户端 mongo
    查看帮助 mongo -help
    退出 exit或者ctrl+c

    2. 关于数据库的基本命令

    功能 命令
    查看当前的数据库
    默认为test数据库
    db
    查看所有的数据库 show dbs 或者 show databases
    切换数据库
    如果数据库<b style='color:red'>不存在,则创建,否则切换</b>到指定数据库
    use db_name
    删除当前的数据库
    注意:先切换到要删除的数据库
    db.dropDatabase()

    3. 关于集合的基础命令

    在mangodb里面没有表的概念,集合就相当于表,不手动创建集合,<b style='color:red'>向不存在的集合中第一次加入数据时,集合就会被创建出来</b>

    语法 说明 举例
    db.createCollection(name,options) 手动创建集合
    (一般很少使用)
    1. db.createCollection('user')
    2.db.createCollection('user2',{capped:true,size:10})
    <b style='color:red'>参数capped:</b>默认值为false表示不设置上限,值为true表示设置上限
    <b style='color:red'>参数size:</b> 当capped值为true时,需要指定此参数,表示上限大小,<u>当文档达到上限时,会将之前的数据覆盖</u>,单位为字节
    show collections 查看集合
    db.集合名称.drop() 删除集合 db.user2.drop()

    4. 关于mangodb数据类型

    类型 说明
    Object ID <b>文档ID</b>
    1、 每个文档都有一个属性,为_id,保证每个文档的<b>唯一性</b>
    2、 可以自己去设置_id插入文档,如果没有提供,那么MongoDB为每个文档提供了一个独特的_id,类型为objectID
    3、 ObjectID是一个<u style='color:blue'>12字节的十六进制数:</u>
      (1)、 前4个字节为当前<u>时间戳</u>
      (2)、 接下来的3个字节的<u>机器ID</u>
      (3)、 接下来的2个字节中<u>MongoDB的服务进程id</u>
      (4)、 最后3个字节是<u>简单的增量值
    <b style='color:red'>String</b> <b>字符串,最常用,必须是有效的UTF-8
    <b style='color:red'>Boolean</b> <b>存储一个布尔值,true或false
    Integer 整数可以是32位或者64位,这取决于服务器
    Double 存储浮点值
    Arrays 数组或者列表,多个值存储到一个键
    Object 用于嵌入式的文档,即一个值为一个文档
    <b style='color:red'>Null</b> <b>存储Null值
    Timestamp 时间戳,表示从1970-1-1到现在的总秒数
    Date <b>存储当前日期或时间的Unix时间格式</b>
    创建日期语句如下:参数的格式为YYYY-MM-DD</br>
    new Date('2018-9-28')</br>

    5. 插入(文档)

    语法 说明 举例
    db.COLLECTION_NAME.insert(document) db.集合名称.insert(文档)
    文档的数据结构和JSON基本一样。
    所有存储在集合中的数据都是BSON格式。
    BSON是一种类json的一种二进制形式的存储格式,简称Binary JSON。
    1、db.test2.insert({name:'zhangsan',age:18})
    2、db.test2.insert({name:'wangwu',age:20,_id:20180101})
    20180924_12

    6. 更新

    6.1、save()

    -- 如果文档的_id已经存在则修改,如果文档的_id不存在则添加
    db.集合名称.save(document)
    
    20180924_14

    6.2、update()

    • 语法
    db.集合名称.update(
       <query>,
       <update>,
       {
         upsert: <boolean>,
         multi: <boolean>,
         writeConcern: <document>
       }
    )
    
    • 参数说明:
      • query : update的查询条件,类似sql update查询内where后面的。
      • update : update的对象和一些更新的操作符(如,inc...)等,也可以理解为sql update查询内set后面的
      • upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
      • multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
      • writeConcern :可选,抛出异常的级别。
    • 举例 1
    -- 把满足条件的全部内容都替换了,age消失了
    db.test2.update({name:'100cxy'},{name:'cxy100'})
    -- 把name为zhangsan的值,替换成zhangsan2
    db.test2.update({name:'zhangsan'},{$set:{name:'zhangsan2'}})
    

    [图片上传失败...(image-1c1af4-1538921093790)]

    • 举例 2
    -- 插入多条数据
    db.test2.insert({name:'wangwu',age:21})
    db.test2.insert({name:'wangwu',age:31})
    db.test2.insert({name:'wangwu',age:41})
    db.test2.insert({name:'wangwu',age:51})
    db.test2.insert({name:'wangwu',age:61})
    

    [图片上传失败...(image-5a7398-1538921093790)]

    -- 把name为wangwu的值更新为maliu
    db.test2.update({name:'wangwu'},{$set:{name:'maliu'}})
    -- 更新多条
    db.test2.update({name:'wangwu'},{$set:{name:'maliu'}},{'multi':true})
    
    20180924_19

    7. 删除

    • 语法
    db.集合名称.remove(<query>,{justOne: <boolean>})
    
    • 参数query:可选,删除的⽂档的条件
    • 参数justOne:可选, 如果设为true或1, 则只删除⼀条, 默认false, 表示删除多条
    • 注意: 默认是删除多条
    20180924_21

    四、mongodb数据查询

    数据准备:

    db.wzry.insert({name:'司马懿',type:'法师',age:1,gender:true})
    
    db.wzry.insert({name:'孙悟空',type:'战士',age:2,gender:true})
    
    db.wzry.insert({name:'后羿',type:'射手',age:3,gender:true})
    
    db.wzry.insert({name:'刘邦',type:'坦克',age:4,gender:true})
    
    db.wzry.insert({name:'花木兰',type:'刺客',age:5,gender:false})
    
    db.wzry.insert({name:'太乙真人',type:'辅助',age:5,gender:true})
    
    db.wzry.insert({name:'蔡文姬',type:'辅助',age:6,gender:false})
    

    [图片上传失败...(image-cb6b6a-1538921093790)]

    数据来源

    1. 数据查询

    方法 命令 举例
    find() 查询
    db.集合名称.find({条件⽂档})
    db.wzry.find({age:5})
    findOne() 查询,只返回第⼀个
    db.集合名称.findOne({条件⽂档})
    db.wzry.findOne({age:5})
    pretty() 将结果格式化
    db.集合名称.find({条件⽂档}).pretty()
    db.wzry.find({age:5}).pretty()

    [图片上传失败...(image-825f8b-1538921093790)]

    2. 比较、范围运算符

    功能 命令 举例
    等于 默认是等于判断, 没有运算符 ...
    小于 $lt (less than) db.wzry.find({ age : { $lt : 5} } )
    小于等于 $lte (less than equal) db.wzry.find({ age : { $lte : 5} } )
    大于 $gt (greater than) db.wzry.find( { age : { $gt : 2 } })
    大于等于 $gte (greater than equal) ...
    不等于 $ne (not equal) ...
    在范围内 $in db.wzry.find( {age : { $in : [4,6] } } )
    不在范围内 $nin db.wzry.find( { age : { $nin : [4,6] } } )

    3、逻辑运算符

    逻辑 举例 说明
    逻辑与 and db.wzry.find({age:5,type:'刺客'}) 在json中写多个条件即可
    逻辑或 or db.wzry.find({$or:[{age:5},{type:'刺客'}]}) 使用$or ,值为数组,数组中每个元素为json

    4、支持正则表达式

    • 使用//或者$regex
    -- 以'后'字开头
    -- 第一种
    db.wzry.find({name:/^后/})
    -- 第二种
    db.wzry.find({name:{$regex:'^后'}})
    

    5、limit和skip

    方法 说明 举例
    limit() 用于读取指定数量的文档 db.wzry.find().limit(2)
    skip() 用于跳过指定数量的文档 db.wzry.find().skip(2)

    6、自定义查询

    • 使⽤$where后⾯写⼀个函数, 返回满⾜条件的数据
    
     <!-- 查询年龄大于5的人物 -->
    
    db.wzry.find({
        $where:function(){
            return this.age>5;
        }
    })
    

    7、投影

    <b style='color:red'>在查询到的返回结果中, 只选择必要的字段</b>

    • 语法
      • db.集合名称.find({},{字段名称:1,...})
      • 参数为字段与值, 值为1表示显示, 值为0不显
      • 特殊: 对于_id列默认是显示的, 如果不显示需要明确设置为0
    • 举例
    db.wzry.find({},{_id:0,name:1,gender:1})
    

    [图片上传失败...(image-c2e3ad-1538921093790)]

    8、排序

    • ⽅法sort(), ⽤于对结果集进⾏排序
    • db.集合名称.find().sort({字段:1,...})
    • 参数1为升序排列
    • 参数-1为降序排列
    -- 按照age升序排序
    db.wzry.find().sort({age:1})
    

    [图片上传失败...(image-7cd3ba-1538921093790)]

    9.统计个数

    • 方法:count() ⽤于统计结果集中⽂档条数

      • db.集合名称.find({条件}).count()
      • db.集合名称.count({条件})
    • 举例

    -- 统计年龄大于等于5的人物
    db.wzry.find({age:{$gte:5}}).count()
    db.wzry.count({age:{$gte:5}})
    

    10.消除重复

    • 方法:distinct() 对数据进行去重

      • db.集合名称.distinct('去重字段',{条件})
    • 举例

    -- 查看所有职业种类
    db.wzry.distinct('type')
    

    五、mongodb聚合(管道与表达式)

    MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。有点类似sql语句中的 count(*)。

    1、aggregate() 方法

    语法:

    db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
    

    聚合的常用表达式:

    语法 说明
    $sum 计算总和, $sum:1 表示以⼀倍计数
    $avg 计算平均值
    $min 获取最⼩值
    $max 获取最⼤值
    $push 在结果⽂档中插⼊值到⼀个数组中
    $first 根据资源⽂档的排序获取第⼀个⽂档数据
    $last 根据资源⽂档的排序获取最后⼀个⽂档数据

    2、管道的概念

    管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。

    MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。

    表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。

    常用操作:

    语法 说明
    $group 将集合中的⽂档分组, 可⽤于统计结果
    $match 过滤数据, 只输出符合条件的⽂档
    $project 修改输⼊⽂档的结构, 如重命名、 增加、 删除字段、 创建计算结果
    $sort 将输⼊⽂档排序后输出
    $limit 限制聚合管道返回的⽂档数
    $skip 跳过指定数量的⽂档, 并返回余下的⽂档
    $unwind 将数组类型的字段进⾏拆分

    3、举例

    3.1、$group 分组统计

    1. 按性别分组,并计算男女人数
    db.wzry.aggregate([
        {
            $group:{
                _id:'$gender',
                num:{
                    $sum:1
                }
            }
        }
    ])
    

    说明:

    • _id:"gender"表示按照gender属性分组;
    • $sum表示求和,如果是$sum:1就相当于count(*),一行记录算一个
    1. 按性别分组,计算年龄和:
    db.wzry.aggregate([
        {
            $group:{
                _id:'gender',
                num:{$sum:'age'}
            }
        }
    ])
    
    1. 按照性别分组,并拿到每个组的第一个年龄:
    db.wzry.aggregate([
        {
            $group:{
                _id:"$gender",
                num:{
                    $first:'$age'
                }
            }
        }
    ])
    
    1. 先按性别分组,分组之后将age属性映射到数据中:(相当于分组之后查看同组的数据,MySQL不能实现)
    db.wzry.aggregate([
        {$group:{
            _id:'$gender',
            num:{$push:'$age'}
        }}
    ])
    

    [图片上传失败...(image-11a205-1538921093790)]

    3.2 $match管道: 类似find,只是find不能统计,现在是可以过滤并统计

    1. 查询年龄大于3且小于等于5的(只是过滤)
    db.wzry.aggregate([
        {
            $match:{
                age:{$gt:3,$lte:5}
            }
        }
    ])
    
    wengwengyu_100cxy.com_20181007_04
    1. 在上面过滤的基础上再集合(先过滤,再分组)
    db.wzry.aggregate([
        {
            $match:{
                age:{$gt:3,$lte:5}
            },
            
        },
        {
            $group:{
                _id:"$gender",
                num:{
                    $num:1
                }
            }
        }
    ])
    

    3.3 $project 修改输入文档的结构.可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档,类似于find方法的第二个参数

    1. 查询年龄大于3或者小于等于5,按照性别分组并且统计人数,并且只取人数列
    db.wzry.aggregate([
        {
            $match:{
                age:{$gt:3,$lte:5}
            }
        },
        {
            $group:{
                _id:'$gender',
                num:{
                    $sum:1
                }
            }
        },
        {
            $project:{
                _id:0,
                num:1
            }
        }
    ])
    

    说明: $project:{_id:0,num:1}表示在结果中取num列,不取_id列

    六、索引和备份

    6.1、 数据的备份

    6.1.1、备份的语法

    mongoddump -h dbhost -d dbname -o dbdirectory
    

    6.1.2、参数说明

    • -h:服务器地址,也可以指定端口号
    • -d:需要备份的数据库名称
    • -o:备份的数据存放位置,此目录中存放着备份出来的数据

    6.1.3、举例

    mongoddump -h 127.0.0.1:27017 -d wzry -o ~/桌面/wzrybak
    

    6.2、数据的恢复

    6.2.1、恢复语法

    • 恢复语法
    mongorestore -h dbhost -d dbname --dir dbdirectory
    

    6.2.2、参数说明

    • h: 服务器地址
    • d:  需要恢复的数据库实例
      --dir: 备份数据所在位置

    6.2.3、举例

    mongorestore -h 127.0.0.1:27017 -d wzry --dir ~/桌面/wzrybak/wzry
    

    七、mongo和python交互

    1、Pymongo

    PyMongo是Mongodb的Python接口开发包,是使用python和Mongodb的推荐方式

    官方文档

    2、安装

    sudo pip install pymongo
    
    wengwengyu_100cxy.com_20181007_02

    3、使用

    1、导入模块

    import pymongo
    # 或者
    from pymongo import MongoClient
    

    2、建立与MongoClient的连接

    client = MongoClient('localhost',27017)
    # 或者
    client = MongoClient('mongodb://localhost:27017/')
    

    3、得到数据库

    db = client.数据库名
    # 或者
    db = client['数据库名']
    

    4、得到一个数据集合

    collection = db.集合名称
    # 或者 
    collection = db['集合名称']
    

    5、主要方法

    • insert_one:加入一条文档对象
    • insert_many:加入多条文档对象
    • find_one:查找一条文档对象
    • find:查找多条文档对象
    • update_one:更新一条文档对象
    • update_many:更新多条文档对象
    • delete_one:删除一条文档对象
    • delete_many:删除多条文档对象

    6、插入方法

    • insert_one() 传入一个字典,表示插入一个文档
    • insert_many() 传入一个列表,列表的元素为字典,插入多条文档
    from pymongo import *
    '''
    插入方法:
        insert_one() 传入一个字典,表示插入一个文档
        insert_many() 传入一个列表,列表的元素为字典,插入多条文档
    '''
    def insert():
        try:
            # 1 创建连接对象
            client = MongoClient(host="localhost", port=27017)
            # 2 获取数据库,
            # 如果这个数据库不存在,就在内存中虚拟创建
            # 当在库里创建集合的时候,就会在物理真实创建这个数据库
            db = client.demo    # 使用demo数据库
            # 向stu集合插入数据
            # 插入一条
            db.stu.insert_one({"name": "zs", "age": 20})
            # 插入多条
            db.stu.insert_many([{"name": 1}, {"name": 2}])
        except Exception as e:
            print(e)
    
    
    if __name__ == '__main__':
        insert()
    

    7、查询方法

    • find_one()返回满足条件的文档集中第一条数据,类型为字典,如果没有查询结果返回None
    • 方法find()返回满足条件的所有文档,类型为Cursor对象,可以使用for...in遍历,每项为字典对象,如果没有查询结果返一个空的Cursor对象
    from pymongo import *
    '''
    查询方法:
        find_one()返回满足条件的文档集中第一条数据,类型为字典
                    如果没有查询结果返回None
        方法find()返回满足条件的所有文档,类型为Cursor对象,可以使用for...in遍历,每项为字典对象
                如果没有查询结果返一个空的Cursor对象
    '''
    def select():
        try:
            # 1 创建连接对象
            client = MongoClient(host="localhost", port=27017)
            # 2 获取数据库,
            # 如果这个数据库不存在,就在内存中虚拟创建
            # 当在库里创建集合的时候,就会在物理真实创建这个数据库
            db = client.demo    # 使用demo数据库
            # 从stu查询数据
            # 查询一条,返回一个字典,如果没有结果返回None
            res = db.stu.find_one({"age": 18})
            print(res)
            # 查询全部结果,返回一个Cursor可迭代对象,每一个元素是字典
            # 如果没有查询结果会返回一个空的Cursor对象
            res = db.stu.find({"age": {"$gt": 18}})
            print(res)
        except Exception as e:
            print(e)
    
    
    if __name__ == '__main__':
        select()
    

    8、修改方法

    • update_one()修改满足条件的文档集中的第一条文档
    • update_many()修改满足条件的文档集中的所有文档
    • 注意:使用$set操作符修改特定属性的值,否则会修改整个文档
    from pymongo import *
    '''
    修改方法:
        update_one()修改满足条件的文档集中的第一条文档
        update_many()修改满足条件的文档集中的所有文档
        注意:使用$set操作符修改特定属性的值,否则会修改整个文档
    '''
    def update():
        try:
            # 1 创建连接对象
            client = MongoClient(host="localhost", port=27017)
            # 2 获取数据库,
            # 如果这个数据库不存在,就在内存中虚拟创建
            # 当在库里创建集合的时候,就会在物理真实创建这个数据库
            db = client.demo    # 使用demo数据库
            # 修改数据
            # 修改第一条符合条件的数据,传入条件和修改结果
            db.stu.update_one({"age": 18},{"$set": {"age": 100}})  # 把年龄是18的第一条年龄改成100
            # 所有符合条件数据都修改
            # db.stu.update_many({"age": 18},{"$set": {"age": 100}}) # 年龄18的所有数据年龄改成100
        except Exception as e:
            print(e)
    
    
    if __name__ == '__main__':
        update()
    

    9、删除方法

    • delete_one()删除满足条件的文档集中第一条文档
    • delete_many()删除满足条件的所有文档
    • 注意:使用$set操作符修改特定属性的值,否则会修改整个文档
    from pymongo import *
    '''
    删除方法:
        delete_one()删除满足条件的文档集中第一条文档
        delete_many()删除满足条件的所有文档
        注意:使用$set操作符修改特定属性的值,否则会修改整个文档
    '''
    def delete():
        try:
            # 1 创建连接对象
            client = MongoClient(host="localhost", port=27017)
            # 2 获取数据库,
            # 如果这个数据库不存在,就在内存中虚拟创建
            # 当在库里创建集合的时候,就会在物理真实创建这个数据库
            db = client.demo    # 使用demo数据库
            # 修改数据
            # 修改第一条符合条件的文档删除
            db.stu.delete_one({"age": 18})  # 把年龄是18的第一条文档删除
            # 所有符合条件数据都删除
            db.stu.delete_many({"age": 18}) # 年龄18的所有文档删除
        except Exception as e:
            print(e)
    
    
    if __name__ == '__main__':
        delete()
    

    相关文章

      网友评论

        本文标题:MongoDB快速入门

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