欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MongoDB快速入门

程序员文章站 2022-06-03 13:33:03
...
MongoDB快速入门
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中的一些概念
MongoDB快速入门
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})
MongoDB快速入门
20180924_12

6. 更新

6.1、save()

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

6.2、update()

  • 语法
db.集合名称.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)
  • 参数说明:
    • query : update的查询条件,类似sql update查询内where后面的。
    • update : update的对象和一些更新的操作符(如MongoDB快速入门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})
MongoDB快速入门
20180924_19

7. 删除

  • 语法
db.集合名称.remove(<query>,{justOne: <boolean>})
  • 参数query:可选,删除的⽂档的条件
  • 参数justOne:可选, 如果设为true或1, 则只删除⼀条, 默认false, 表示删除多条
  • 注意: 默认是删除多条
MongoDB快速入门
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}
        }
    }
])
MongoDB快速入门
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
MongoDB快速入门
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()