• Python开发之基础Mongodb


    Mongodb简介

    Mongodb是一个分布式存储的NoSQL数据库,运行稳定、性能高,旨在于为WEB应用提供可扩展的高性能数据存储解决方案。

    MongoDB特点:

    • 模式自由:可以把不同结构的文档存储在同一个数据库中。
    • 面向集合的存储:适合存储JSON风格格式的形式
    • 完整的索引支持:对任何属性可索引
    • 复制和高可用性:支持服务器之间的数据复制,支持主从模式以及服务器之间的相互复制。复制的主要目的是提供冗余及自动故障转移。
    • 自动分片:支持云级别的伸缩性,自动分片功能支持水平的数据库集群,可动态添加额外的机器。
    • 丰富的查询:支持丰富的查询表达方式,查询指令使用JSON形式的标记,可轻易的查询文档中的内嵌的对象以及数组
    • 快速就地更新:查询优化器会分析查询表达式,并生成一个高效的查询计划
    • 高效的传统存储方式:支持二进制数据以及大型数据。

    Mongodb中的名词

    SQL术语 MongoDB术语 说明
    database database 数据库
    table collection 数据库表/集合
    row document 数据记录行/文档
    column filed 数据字段/域
    index index 索引
    table joins   表连接,MongoDB不支持
    primary key primary key 主键,MongoDB自动将id设置为主键

    MongoDB中的三元素:数据库、集合、文档。

    集合就是关系型数据库中的表

    文档就是对应关系数据库中的行,文档就是一个对象,由键值对组成,是json的扩展Bson形式

    数据库安装 

    1、下载完安装包,并解压 tgz

    curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.6.tgz    # 下载
    tar -zxvf mongodb-linux-x86_64-3.0.6.tgz                                   # 解压
    
    mv  mongodb-linux-x86_64-3.0.6/ /usr/local/mongodb    
    

    2、MongoDB 的可执行文件位于 bin 目录下,所以可以将其添加到 PATH 路径中:

    export PATH=/usr/local/mongodb/bin:$PATH
    

    3、MongoDB的数据存储在data目录的db目录下,但是这个目录在安装过程不会自动创建,所以你需要手动创建data目录,并在data目录中创建db目录。

    mkdir -p /data/db

    4、你可以在命令行中执行mongo安装目录中的bin目录执行mongod命令来启动mongdb服务。

    ./mongod
    2018-08-15T22:03:29.771+0800 I STORAGE  [initandlisten] exception in initAndListen: 98 Unable to create/open lock file: /data/db/mongod.lock errno:13 Permission denied Is a mongod instance already running?, terminating
    2018-08-15T22:03:29.771+0800 I CONTROL  [initandlisten] dbexit:  rc: 100

    如果你在安装目录下执行./mongod报上述错误,表示没有权限,所以就要加权限

    sudo chmod 777 -R /data

    再次执行./mongod

    5、MongoDB后台管理Shell

    如果你需要进入MongoDB后台管理,你需要先打开mongodb装目录的下的bin目录,然后执行mongo命令文件。

    MongoDB Shell是MongoDB自带的交互式Javascript shell,用来对MongoDB进行操作和管理的交互式环境。

    python@python:/usr/local/mongodb/bin$ ./mongo
    MongoDB shell version: 3.0.6
    connecting to: test
    Welcome to the MongoDB shell.
    For interactive help, type "help".
    For more comprehensive documentation, see
        http://docs.mongodb.org/
    Questions? Try the support group
        http://groups.google.com/group/mongodb-user
    > 
    > 
    > 2+3
    5

    6、MongoDB web用户界面

    MongoDB 提供了简单的 HTTP 用户界面。 如果你想启用该功能,需要在启动的时候指定参数 --rest 。

    注意:该功能只适用于 MongoDB 3.2 及之前的早期版本。

    $ ./mongod --dbpath=/data/db --rest

    MongoDB 的 Web 界面访问端口比服务的端口多1000。

    如果你的MongoDB运行端口使用默认的27017,你可以在端口号为28017访问web用户界面,即地址为:http://localhost:28017。

    数据库基本操作

    1、数据库切换

    查看当前数据库名称
    > db
    test
    查看所有数据库名称
    > show dbs
    local  0.078GB
    创建数据库
    > use test1
    switched to db tst

    2、数据库删除

    数据库删除
    db.dropDatabase

    3、数据集合

    MongoDB 中使用 createCollection() 方法来创建集合。
    db.createCollection(name, options)
    参数说明:
    name: 要创建的集合名称
    options: 可选参数, 指定有关内存大小及索引的选项

    options 可以是如下参数:

    字段 类型 描述
    capped 布尔 (可选)如果为 true,则创建固定集合。固定集合是指有着固定大小的集合,当达到最大值时,它会自动覆盖最早的文档。
    当该值为 true 时,必须指定 size 参数。
    autoIndexId 布尔 (可选)如为 true,自动在 _id 字段创建索引。默认为 false。
    size 数值 (可选)为固定集合指定一个最大值(以字节计)。
    如果 capped 为 true,也需要指定该字段。
    max 数值 (可选)指定固定集合中包含文档的最大数量。

    在插入文档时,MongoDB 首先检查固定集合的 size 字段,然后检查 max 字段。

    •  不限制集合的大小
    > db.createCollection("name")
    { "ok" : 1 }
    • 创建固定集合 mycol,整个集合空间大小 6142800 KB, 文档最大个数为 10000 个。
    > db.createCollection("mycol",{capped:true,autoIndexId:true,size:8142800,max:10000})
    { "ok" : 1 }
    • 如果要查看已有集合,可以使用 show collections 命令:
    > show collections
    mycol
    name
    runoob
    system.indexes
    • 删除集合:db.集合名称.drop()
    > db.mycol.drop()
    true

    4、数据类型

    常见数据类型

    • Object ID:文档类型
    • String:字符串,最常用必须是UTF-8
    • Boolean:存储一个布尔值,true或false
    • Integer:整数可以是32位或64位,取决于服务器
    • Double:存储浮点数
    • Arrays:数组或列表,多个值存储到一个键
    • Object:用于嵌入式的文档,即一个值为一个文档
    • Null:存储Null值
    • Timestamp:时间戳
    • Date:存储当前日期的UNIX时间格式

    5、插入

    MongoDB 使用 insert() 或 save() 方法向集合中插入文档,语法如下:

    db.COLLECTION_NAME.insert(document)
    > db.mycol.insert({title:'Mongodb',descr:'课程'})
    WriteResult({ "nInserted" : 1 })
    > show dbs

    6、查找

    > db.mycol.find()
    { "_id" : ObjectId("5b7589f65591ee81f5f24102"), "title" : "Mongodb" }
    { "_id" : ObjectId("5b758a145591ee81f5f24103"), "title" : "Mongodb", "descr" : "课程" }

    更新

    update() 方法用于更新已存在的文档。语法格式如下:

    db.collection.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 :可选,抛出异常的级别。
    > db.mycol.find()
    { "_id" : ObjectId("5b7589f65591ee81f5f24102"), "title" : "Mongodb" }
    { "_id" : ObjectId("5b758a145591ee81f5f24103"), "title" : "Mongodb", "descr" : "课程" }
    { "_id" : ObjectId("5b758bc25591ee81f5f24104"), "name" : "hr", "age" : "18" }
    > db.mycol.update({name:'hr'},{name:"gj"})
    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    > db.mycol.find()
    { "_id" : ObjectId("5b7589f65591ee81f5f24102"), "title" : "Mongodb" }
    { "_id" : ObjectId("5b758a145591ee81f5f24103"), "title" : "Mongodb", "descr" : "课程" }
    { "_id" : ObjectId("5b758bc25591ee81f5f24104"), "name" : "gj" }

    以上语句只会修改第一条发现的文档,如果你要修改多条相同的文档,则需要设置 multi 参数为 true

    > db.mycol.update({},{$set:{title:'python'}},{multi:true})
    WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 2 })
    > db.mycol.find()
    { "_id" : ObjectId("5b7589f65591ee81f5f24102"), "title" : "python" }
    { "_id" : ObjectId("5b758a145591ee81f5f24103"), "title" : "python", "descr" : "课程" }
    { "_id" : ObjectId("5b758bc25591ee81f5f24104"), "name" : "gj", "title" : "python" }

    7、保存

    save() 方法通过传入的文档来替换已有文档。语法格式如下:

    db.collection.save(
       <document>,
       {
         writeConcern: <document>
       }
    )
    参数说明:
    
    document : 文档数据。
    writeConcern :可选,抛出异常的级别。
    > db.mycol.save({name:'java'})
    WriteResult({ "nInserted" : 1 })
    > db.mycol.find()
    { "_id" : ObjectId("5b7589f65591ee81f5f24102"), "title" : "python" }
    { "_id" : ObjectId("5b758a145591ee81f5f24103"), "title" : "python", "descr" : "课程" }
    { "_id" : ObjectId("5b758bc25591ee81f5f24104"), "name" : "gj", "title" : "python" }
    { "_id" : ObjectId("5b758e725591ee81f5f24105"), "name" : "java" }

    8、删除文档

    remove() 方法的基本语法格式如下所示:
    db.collection.remove(
       <query>,
       <justOne>
    )
    > db.mycol.find()
    { "_id" : ObjectId("5b7589f65591ee81f5f24102"), "title" : "python" }
    { "_id" : ObjectId("5b758a145591ee81f5f24103"), "title" : "python", "descr" : "课程" }
    { "_id" : ObjectId("5b758bc25591ee81f5f24104"), "name" : "gj", "title" : "python" }
    { "_id" : ObjectId("5b758e725591ee81f5f24105"), "name" : "java" }
    > db.mycol.remove({title:'python'})
    WriteResult({ "nRemoved" : 3 })
    > db.mycol.find()
    { "_id" : ObjectId("5b758e725591ee81f5f24105"), "name" : "java" }

    全部删除

    > db.mycol.remove({})

    9、数据查询

    MongoDB 查询数据的语法格式如下:

    db.collection.find(query, projection)
    query :可选,使用查询操作符指定查询条件
    projection :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需省略该参数即可(默认省略)。
    如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:
    >db.col.find().pretty()
    > db.mycol.findOne()
    { "_id" : ObjectId("5b7592253a1d5dd1beb2b7ac"), "title" : "js" }
    > db.mycol.find().pretty()
    { "_id" : ObjectId("5b7592253a1d5dd1beb2b7ac"), "title" : "js" }
    { "_id" : ObjectId("5b75922d3a1d5dd1beb2b7ad"), "title" : "python" }

    10、条件操作符

    MongoDB中条件操作符有:
    
    (>) 大于 - $gt
    (<) 小于 - $lt
    (>=) 大于等于 - $gte
    (<= ) 小于等于 - $lte
    > db.mycol.insert({age:12})
    WriteResult({ "nInserted" : 1 })
    > db.mycol.find({'age':{$lt:13}})
    { "_id" : ObjectId("5b7593845591ee81f5f24107"), "age" : 12 }
    Select * from mycol where age < 13;

    11、模糊匹配

    查询 title 包含""字的文档:
    
    db.col.find({title:/教/})
    查询 title 字段以""字开头的文档:
    
    db.col.find({title:/^教/})
    查询 titl e字段以""字结尾的文档:
    
    db.col.find({title:/教$/})

     12、使用函数查询,其实就是js

    > db.mycol.find({$where: function(){return this.age==12}} )
    { "_id" : ObjectId("5b7593385591ee81f5f24106"), "age" : "12" }
    { "_id" : ObjectId("5b7593845591ee81f5f24107"), "age" : 12 }

    13、limit

    如果你需要在MongoDB中读取指定数量的数据记录,可以使用MongoDB的Limit方法,limit()方法接受一个数字参数,该参数指定从MongoDB中读取的记录条数。

    > db.mycol.find().limit(2)
    { "_id" : ObjectId("5b7592253a1d5dd1beb2b7ac"), "title" : "js" }
    { "_id" : ObjectId("5b75922d3a1d5dd1beb2b7ad"), "title" : "python" }

    我们除了可以使用limit()方法来读取指定数量的数据外,还可以使用skip()方法来跳过指定数量的数据,skip方法同样接受一个数字参数作为跳过的记录条数。

    > db.mycol.find()
    { "_id" : ObjectId("5b7592253a1d5dd1beb2b7ac"), "title" : "js" }
    { "_id" : ObjectId("5b75922d3a1d5dd1beb2b7ad"), "title" : "python" }
    { "_id" : ObjectId("5b7593385591ee81f5f24106"), "age" : "12" }
    { "_id" : ObjectId("5b7593845591ee81f5f24107"), "age" : 12 }
    > db.mycol.find().limit(2)
    { "_id" : ObjectId("5b7592253a1d5dd1beb2b7ac"), "title" : "js" }
    { "_id" : ObjectId("5b75922d3a1d5dd1beb2b7ad"), "title" : "python" }
    > db.mycol.find().limit(2).skip(1)
    { "_id" : ObjectId("5b75922d3a1d5dd1beb2b7ad"), "title" : "python" }
    { "_id" : ObjectId("5b7593385591ee81f5f24106"), "age" : "12" }
    > db.mycol.find().limit(2).skip(2)
    { "_id" : ObjectId("5b7593385591ee81f5f24106"), "age" : "12" }
    { "_id" : ObjectId("5b7593845591ee81f5f24107"), "age" : 12 }

    14、排序

    在 MongoDB 中使用 sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。

    > db.mycol.find().sort({"age":-1})
    { "_id" : ObjectId("5b7593385591ee81f5f24106"), "age" : "12" }
    { "_id" : ObjectId("5b7593845591ee81f5f24107"), "age" : 12 }
    { "_id" : ObjectId("5b75922d3a1d5dd1beb2b7ad"), "title" : "python" }
    { "_id" : ObjectId("5b7592253a1d5dd1beb2b7ac"), "title" : "js" }
    > db.mycol.find().sort({"age":-1,"title":1})
    { "_id" : ObjectId("5b7593385591ee81f5f24106"), "age" : "12" }
    { "_id" : ObjectId("5b7593845591ee81f5f24107"), "age" : 12 }
    { "_id" : ObjectId("5b7592253a1d5dd1beb2b7ac"), "title" : "js" }
    { "_id" : ObjectId("5b75922d3a1d5dd1beb2b7ad"), "title" : "python" }

    15、统计

    > db.sub.find()
    { "_id" : ObjectId("5b7591b73a1d5dd1beb2b7aa"), "title" : "java" }
    { "_id" : ObjectId("5b7591d23a1d5dd1beb2b7ab"), "title" : "python" }
    { "_id" : ObjectId("5b759ade5591ee81f5f24108"), "title" : "c++" }
    { "_id" : ObjectId("5b759ae35591ee81f5f24109"), "title" : "js" }
    { "_id" : ObjectId("5b759ae75591ee81f5f2410a"), "title" : "css" }
    > db.sub.find().count()
    5

    MongoDB聚合操作

    聚合

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

    MongoDB中聚合的方法使用aggregate()。

    聚合框架中常用的几个操作:
    
    $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
    $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
    $limit:用来限制MongoDB聚合管道返回的文档数。
    $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
    $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
    $group:将集合中的文档分组,可用于统计结果。
    $sort:将输入文档排序后输出。
    $geoNear:输出接近某一地理位置的有序文档
    > db.sub.aggregate([{$group:{"_id":'$title',counter:{$sum:1}}}])
    { "_id" : "css", "counter" : 1 }
    { "_id" : null, "counter" : 3 }
    { "_id" : "js", "counter" : 1 }
    { "_id" : "python", "counter" : 1 }
    { "_id" : "c++", "counter" : 1 }
    { "_id" : "java", "counter" : 1 }

    $match用于过滤数据,只显示符合条件的文档

    > db.sub.find()
    { "_id" : ObjectId("5b7591b73a1d5dd1beb2b7aa"), "title" : "java" }
    { "_id" : ObjectId("5b7591d23a1d5dd1beb2b7ab"), "title" : "python" }
    { "_id" : ObjectId("5b759ade5591ee81f5f24108"), "title" : "c++" }
    { "_id" : ObjectId("5b759ae35591ee81f5f24109"), "title" : "js" }
    { "_id" : ObjectId("5b759ae75591ee81f5f2410a"), "title" : "css" }
    { "_id" : ObjectId("5b759ea05591ee81f5f2410b"), "price" : 12000 }
    { "_id" : ObjectId("5b759ea45591ee81f5f2410c"), "price" : 11000 }
    { "_id" : ObjectId("5b759eaa5591ee81f5f2410d"), "price" : 10000 }
    > db.sub.aggregate([{$match:{'price':{$gt:10000}}}])
    { "_id" : ObjectId("5b759ea05591ee81f5f2410b"), "price" : 12000 }
    { "_id" : ObjectId("5b759ea45591ee81f5f2410c"), "price" : 11000 }

    $project():修改输入文档的结构,如重命名,增加、删除字段、创建计算结果

    例如:只显示counter,不显示id

    > db.sub.aggregate([{$group:{"_id":'$title',counter:{$sum:1}}},{$project:{_id:0,counter:1}}])
    { "counter" : 1 }
    { "counter" : 3 }
    { "counter" : 1 }
    { "counter" : 1 }
    { "counter" : 1 }
    { "counter" : 1 }

    $limit:限制聚合管道返回额文档数

    > db.sub.find()
    { "_id" : ObjectId("5b7591b73a1d5dd1beb2b7aa"), "title" : "java" }
    { "_id" : ObjectId("5b7591d23a1d5dd1beb2b7ab"), "title" : "python" }
    { "_id" : ObjectId("5b759ade5591ee81f5f24108"), "title" : "c++" }
    { "_id" : ObjectId("5b759ae35591ee81f5f24109"), "title" : "js" }
    { "_id" : ObjectId("5b759ae75591ee81f5f2410a"), "title" : "css" }
    { "_id" : ObjectId("5b759ea05591ee81f5f2410b"), "price" : 12000 }
    { "_id" : ObjectId("5b759ea45591ee81f5f2410c"), "price" : 11000 }
    { "_id" : ObjectId("5b759eaa5591ee81f5f2410d"), "price" : 10000 }
    > db.sub.aggregate([{$limit:2}])
    { "_id" : ObjectId("5b7591b73a1d5dd1beb2b7aa"), "title" : "java" }
    { "_id" : ObjectId("5b7591d23a1d5dd1beb2b7ab"), "title" : "python" }

    $skip

    > db.sub.aggregate([{$limit:2}])
    { "_id" : ObjectId("5b7591b73a1d5dd1beb2b7aa"), "title" : "java" }
    { "_id" : ObjectId("5b7591d23a1d5dd1beb2b7ab"), "title" : "python" }
    > db.sub.aggregate([{$limit:2},{$skip:1}])
    { "_id" : ObjectId("5b7591d23a1d5dd1beb2b7ab"), "title" : "python" }

     $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。

    > db.t2.find()
    { "_id" : 1, "item" : "t-shirt", "size" : [ "S", "M", "L" ] }
    > db.t2.aggregate([{$unwind:'$size'}])
    { "_id" : 1, "item" : "t-shirt", "size" : "S" }
    { "_id" : 1, "item" : "t-shirt", "size" : "M" }
    { "_id" : 1, "item" : "t-shirt", "size" : "L" }
  • 相关阅读:
    博客园样式设置
    最坏情况为线性时间的选择算法
    棋盘覆盖
    矩阵乘法的Strassen算法及时间复杂度
    大整数乘法及算法时间复杂度
    全排列问题的递归算法(Perm)
    python的lambda
    python的zip函数
    python操作队列
    mysql基础命令
  • 原文地址:https://www.cnblogs.com/crazyforever/p/9074080.html
Copyright © 2020-2023  润新知