MongoDB

MongoDB

MongoDB是一个高性能、开源、无模式的文档类型数据库。

MongoDB的性能

  • 对数据库高并发请求
  • 对海量数据的高效率存储和访问需求
  • 对数据库的高可扩展性

NoSQL特点

  1. 可以处理超大量的数据
  2. 可以运行在PC服务器集群上PC

MongoDB的特点

MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库中功能最丰富、最像关系型数据库的。它支持的数据结构是比较松散的,是类似json的bjson格式,因此可以存储比较复杂的数据类型。MongoDB最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象查询语句,可以实现类似关系数据库单表查询的绝大部分功能,而且还支持数据建立索引。它是一个面向集合的,模式自由的文档型数据库

面向集合(Collection-Oriented)

数据被分组存储在数据集中,被称为一个集合(Collection)。每个集合在数据库中都有一个唯一的标识名,并且可以包含无限数目的文档。集合的概念类似关系型数据库里的表(table),不同的是它不需要定义任何模式(schema)

模式自由(Schema-free)

对于存储在MongoDB数据库中的文件,我们不需要知道它的任何结构定义,例如以下两个记录可以放在同一个集合里,即在关系数据库里,一个表有(name,age),那么所有创建的对象就有这两个属性,但是mongoDB中不需要。

{"Welcome":"Beijing"}
{"age":20}

文档型

我们存储的数据是键-值对的集合,键是字符串,值可以是数据类型集合里的任意类型,包括数组和文档,我们把这个格式叫做BSON(Binary Serialized document Notation)

适用场景

  • 网站数据:MongoDB非常适合实时的插入,更新和查询,并具备网站实时数据存储所需的复制及高度伸缩性
  • 缓存:由于性能高,MongoDB也适合作为信息基础设施的缓存层,在系统重启之后,由MongoDB搭建的持久化缓存层可以避免下层的数据源过载
  • 大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据可能会比较昂贵,这时就可以采用MongoDB
  • 高伸缩性场景:MongoDB非常适合由数十或数百台服务器组成的数据库
  • 用于对象及JSON数据的存储:MongoDB的BSON数据格式非常适合文档化格式的存储及查询

MongoDB安装

  1. 可以自行官网下载安装包
  2. 配置环境变量
  • 找到mongoDB安装路径,进入到bin目录下,保存此文件路径,如: C:\Users\mongoDB\bin
  • 右键点击此电脑->属性->高级系统设置->高级->环境变量->编辑用户的变量path->将上面的路径添加进去
  1. 在安装MomgoDB文件夹的根目录新建一个文件夹data,在data中新建一个文件夹db,进入到mongoDB/bin的目录下,执行以下命令:
    mongod --dbpath E:\ data\ db
  2. 启动mongoDB,此窗口为mongoDB服务器,cmd输入: mongod (出现waiting for connecting port xx即表示成功开启服务)
  3. 重新开启一个cmd窗口,此窗口为mongoDB客户端,cmd输入:mongo 进行连接,当此窗口出现”>”,进行简单操作验证是否成功

图形化界面操作

可以使用robo3/mongoDB Compass图形界面

MongoDB的操作

MongoDB与SQL的概念对比

SQL MongoDB
database database
table collection
row document or BSON document
column field
index index
primary key _id(auto set)

数据类型

以下是几种MongoDB常用的数据类型:

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

Object ID

  1. 每个文档都有一个属性,为_id,保证每个文档的唯一性
  2. 可以自己设置_id插入文档
  3. 如果没有提供,MongoDB默认为每个文档提供里一个独特的_id,类型为objectID
  4. objectID是一个12字节的16进制数:
  • 前4个字节为时间戳
  • 接下来3个字节的机器ID
  • 接下来的2个字节中MongoDB的服务进程id
  • 最后3个字节是简单的增量值

collection与table的差异】

table

id title content
1 天气 万里无云
2 心情 哈哈

特点:

  • 有结构
  • 行遵循结构

collection

{id:1,title:'万里无云'}
{id:2,title:'哈哈',date:'2020'}

特点:

  • collection无结构
  • 文档相互独立,没有固定的结构

数据库操作

show dbs  #查看已有数据库
use dataName  #选择数据库,如果没有此数据库则新建一个名字为dataName的数据库
use person
show collection #查看已有的集合
db.createCollection("集合名")   #创建集合
db.createCollection("student")
db.集合名.drop()          #删除表 ,先切换到该数据库才能进行删除
db.dropDatabase()    #删除当前数据库

注:如果我们对新创建的数据库没有进行操作,该数据库只是在内存中暂时存放,只有对该数据库进行实际操作后,数据库才会存放在硬盘里

MongoDB数据的基本操作

数据的增加

插入文档时,如果不指定_id参数,MongoDB会为文档分配一个唯一的ObjectID

insert

insert可以一次性插入一个文档,而不用遍历,效率高。insert中只要两个文档id相同就无法进行插入

db.集合名.insert(document)

save

在save方法里,如果不存在重复的对象,则向collection里插入数据,如果已经存在,save会调用update更新集合里的记录。save需要遍历列表,一个个插入,效率较低。save更新相同的id的内容

db.集合名.save(document)

例子

数据库student中有一个{ _ id:”1”,”name”:”zby”}的文档

db.student.insert({"_id":"1","name":"ybz"})    #会报错,主键重复
db.student.save({"_id":"1","name":"ybz"})       #数据库的文档替换成{_id:"1","name":ybz}

插入多个文档

使用列表插入

 db.student.insert([{"name":"zby"},{"name":"ybz"},{"name":"by"}])

效果如图所示:

数据的修改

语法:

db.集合名.update(<query>,<update>,<multi:boolean>)
  • 参数query: 查询条件,类似sql语句update中的where部分
  • 参数update: 更新操作符,类似sql语句update中的set部分
  • 参数multi:可选,默认false,表示只更新找到第一条记录,值为true标识把满足条件的所有文档全部更新

例子

db.student.update({"name":"by"},{"age":18})  #将第一条name为by的文档中的age改为18,并且会改变文档结构,即如果没有age会将name改为age来存储
db.student.update({"name":"by"},{$set:{"age":18}) #只更新数据,不更新文档结构
db.student.update({"name":"by"},{$set:{"age":18},{"multi":true}) #更新所有匹配到的数据

原集合:

  1. 执行

    db.student.update({"name":"bob","age":19})

  2. 继续执行

    db.student.update({"age":19},{$set:{"name":"bob"})

  3. 最后执行

    db.student.insert({"name":"bob","age":35})
    db.student.update({"name":"bob"},{$set:{"age":20},{"multi":true})

简单查询

find

查找到所有匹配数据

db.集合名.find({条件文档})

findOne

只返回匹配的第一个数据

db.集合名.findOne({条件文档})

运算符

语法 操作 格式
$eq 等于 {:}
$lt 小于 {:{$lt:}}
$lte 小于或等于 {:{$lte:}}
$gt 大于 {:{$gt:}}
$gte 大于或等于 {:{$gte:}}
$ne 不等于 {:{$ne:}}
$or {$or:[{},{}]}
$in 在范围内 {age:{$in:[value1,value2]}}
$nin 不在范围内 {age:{$nin:[value1,value2]}}

删除文档

db.student.remove({"name":"bob"})   #删除name=bob的文档
db.student.remove({})    #删除集合里所有文档

例子

db.student.find({"age":{$gt:16}})
db.student.find({$or:[{"age":{$gte:18}},{"name":"bob"}]})

其他操作

模糊匹配

使用//或$regex编写正则表达式

db.student.find({"name":/^bob/})
db.student.find({"name":{$regex:'^bob'}})

limit

用于读取指定数量的文档

db.集合名.find().limit(number)

skip

用于跳过指定数量的文档

db.集合名.find().skip(number)

sort

用于对结果集合进行排序

db.集合名.find().sort({字段1,字段2})
  • 参数1为升序排序
  • 参数-1为降序排序

Python与MongoDB交互

安装环境

在Anaconda Prompt中使用pip安装(直接使用pycharm解释器搜索安装)

pip install pymongo

使用样例

在连接之前要确保mongoDB服务器已经打开

  1. 引入包pymongo

    import pymongo
  2. 连接/创建客户端
    下面是两种连接客户端的方法

    client = pymongo.MongoClient("localhost",27017)  #也可以不传参,默认为本机mongoDB服务器
    client = pymongo.MongoClient("mongodb://localhost:27017")
  3. 获得数据库person
    下面是两种获取数据库的方式

    db = client.person
    db = client['person']
  4. 获得集合student
    下面是两种获取集合的方式

    collection = person.student
    collection = person['student']
  5. 添加文档

    data = {"name":"bai","age":19}
    data2 = {"name":"yang","age":12}
    student.insert_one(data1)  #插入一个文档
    student.insert_many([data1,data2])   #插入多个文档
  6. 查找文档

    target = student.find_one({"name":"bai"})
    target = student.find({"name":"bai"})
  7. 获取文档

    result = student.next()      #一个文档一个文档的取出
  8. 删除文档

    student.remove(data1)    #以文档对象的形式删除
    student.remove({"name":"bai"})   #以field筛选删除
  9. 打印文档

    target1 = student.find_one({"name":"bai"})  #返回一个文档直接打印
    print(target1)
    target2 = list(student.find({"name":"bai"})) #返回多个文档使用list()函数或循环

爬虫爬取信息存放到mongoDB里

创建一个爬虫(见爬虫篇),

spider.py

  1. 先爬取网页,提取要存储进MongoDB的数据
  2. 将提取到数据使用zip进行打包
     def parse(self, response):
         download_urls = response.xpath("//div[@class='cont']/ul//a[@class='btn-b']/@href").extract()  # 获取整页下载链接用getall()
         names = response.xpath("//div[@class='cont']//em//text()").extract()
         update_times = response.xpath("//div[@class='cont']//span[@class='ml10']//text()").extract()
         #将上面抓取到的元素打包成元组
         for download_url,name,update_time in zip(download_urls,names,update_times):
             yield {
                 "name":name,
                 "download_url":download_url,
                 "update_time":update_time,
             }

pipelines.py

  1. 连接mongoDB
  2. 向对应的集合中插入文档
  3. 关闭mongoDB连接
    import pymongo
    class MongodbPipeline(object):
     #连接MongoDB
     def open_spider(self,spider):
         self.client = pymongo.MongoClient()
     def process_item(self, item, spider):
         self.client.s2345.softInfo.insert_one(item)
         return item
     #关闭MongoDB
     def close_spider(self,spider):
         self.client.close()

settings.py

改robots/item_pipelines/user-agent

ITEM_PIPELINES = {
    'xx.pipelines.MongodbPipeline': 300,
}

   转载规则


《MongoDB》 fightingtree 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录