MongoDB数据库--------------------python爬虫知识点9

一、MongoDB介绍

定义

  • MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引
  • 数据存在磁盘中的
  • 语法和mysql还是挺像,不难上手

学习目的

  • 企业需求(要求爬虫开发工程师必须会这个技术)
  • 爬虫的数据如果上了一个量级,使用MongoDB会比Mysql好一些
  • scrapy_redis适用性小(并不是所有的公司都要用分布式)

SQL和NoSQL的主要区别

  • 在SQL中层级关系:数据库->表->数据
  • 在NoSQL中是:数据库->集合->数据

MongoDB的优势

  • 1.无数据结构(方便做爬虫)
    • 没有表结构的概念,每条记录可以有完全不同的结构
    • 业务开发方便快捷
  • 2.高性能(具有非常高的读写性能)
    • nosql数据库都具有非常高的读写性能,尤其在大数量下表现优秀
  • 3.良好的支持(完善的文档 跨平台 稳定)
    • 完善的文档
    • 齐全的驱动支持

MongoDB安装

'''
linux
'''
MongoDB在Ubuntu中安装
在Linux中安装MongoDB
sudo apt-get install mongodb
开启服务
sudo service mongodb start
关闭服务
sudo service mongodb stop
重启服务
sudo service mongodb restart
'''
windows
'''
下载安装包https://www.mongodb.com/download-center/community
把MongoDB的bin目录加入到环境变量中
# 启动MongoDB
mongod --dbpath C:\Program Files\MongoDB\Server\4.4\data  
# 连接MongoDB
mongo

二、语法

SQL概念MongoDB概念解释
databasedatabase数据库
tablecollection数据库表/集合
rowdocument数据记录行/文档
columnfield字段/域
indexindex索引
primary keyprimary key主键

MongoDB三元素

  • 三元素:数据库、集合、文档
    • 文档:就是关系型数据库中的一行。文档是一个对象,由键值对构成,是json的扩展形式
      {"name": "abc", "gender": 1}
      
    • 集合:就是关系型数据库中的。可以存储多个文档,结构可以不固定。
      {"name": "abc", "gender": 1}
      {"name": "abc", "age": 18}
      {"title": "abc", "price": 1}
      

MongoDB的数据类型

  • String:字符串,必须是有效的UTF-8
  • Boolean:存储一个布尔值,true或者false
  • Integer:整数可以是32位或64位,这取决于服务器
  • Double:存储浮点数
  • Arrays:数组或列表
  • Object:嵌入式文档
  • Null:存储Null值
  • Timestamp:时间戳, 表示从1970-1-1到现在的总秒数
  • Object ID是一个12字节的十六进制数

数据库命名规范

  • 1.不能是空字符串
  • 2.不得含有特殊字符
  • 3.应全部小写
  • 4.最多64个字节
  • 5.数据库名不能与现有系统保留库同名,如admin,local

(一)基本语法

数据库命令说明
show dbs查看数据库
use 数据库切换、创建数据库
db查看当前的数据库
db.dropDatabase()删除数据库
集合命令说明
db.createCollection(name,options)手动创建集合
use 数据库切换、创建数据库
db查看当前的数据库
db.dropDatabase()删除数据库
show tables/show collections查看集合
db.集合名称.drop()删除集合

重点参数说明:

  • name: 要创建的集合名称
  • options: 可选参数, 指定有关内存大小及索引的选项
    • 参数capped:默认值为false表示不设置上限,值为true表示设置上限
    • 参数size:当capped值为true时,需要制定此参数。表示上限大小,当文档达到上限时,会将之前的数据覆盖,单位为字节

(二)修改数据

  • db.集合名.insert({}) 数据格式为json,id不能重复,支持多条插入数据库
**单条插入数据**
- db.jerry_collection.insert({x:1})

**多条插入数据**
- for(i=3;i<10;i++)db.jerry3.insert({x:i}) # 函数方式
- db.stu.insert([{"name" : "张三", "hometown" : "长沙", "age" : 20, "gender" : true },
{"name" : "老李", "hometown" : "广州", "age" : 18, "gender" : false },
{"name" : "王麻子", "hometown" : "北京", "age" : 18, "gender" : false },
{"name" : "刘六", "hometown" : "深圳", "age" : 40, "gender" : true },
{"name" : "jerry", "hometown" : "长沙", "age" : 16, "gender" : true },
{"name" : "小永", "hometown" : "广州", "age" : 45, "gender" : true },
{"name" : "老amy", "hometown" : "衡阳", "age" : 18, "gender" : true }])

保存数据

  • 命令:db.集合名称.save(document)
    db.stu.save({_id:ObjectId("5f169b37d74866264ed9a7db"), name:'gj', gender:2})
    db.stu.save({name:'gj', gender:2})
    db.stu.find()
    

修改数据

  • db.集合名称.update({query}, {update}, {multi: boolean})
    • 参数query:查询条件
      参数update:更新操作符
      参数multi:可选,默认是false,表示只更新找到的第一条数据,值为true表示把满足条件的数据全部更新
      # 全部修改
      db.jerry_collection.update({x:100},{y:99})
      	#修改后数据变为  
      	#{ "_id" : ObjectId("59b297dd8fa0c171faae5bc8"), "y" : 99 }
      
      # 部分更新
      db.jerry_collection.update({x:100},{$set:{y:99}})
      
      # 如果查询条件并不存在,则插入该数据,将第三个参数设为true
      db.jerry_collection.update({y:100},{y:101},true)
      
      # 满足的全部更新
      db.jerry_collection.update({y:99},{$set:{y:101}},{multi:true})
      

删除数据

  • db集合名称.remove({条件},{justOne:true})
  • 不能撤销,也不能恢复,因此,在执行 remove() 函数前最好先用 find() 命令来查看是否正确。
    • query:设置删除的数据的条件,mongoDB为了防止误删除,条件必须写。
      justOne:布尔型的可选项,默认为false,删除符合条件的所有文档,如果设为 true,则只删除一个文档。
    # 删除所有x=100的数据
    db.jerry_collection.remove({x:100})
    

(三)查询数据

查询所有数据

  • db.集合名称.find()

查询单条数据

  • db.集合名称.findOne()

带有条件的查询

  • db.集合名称.find({条件})
    • 查询字段等于某值: {字段1:值1,字段2:值2,…}
      查询x等于100的数据
      db.jerry_collection.find({x:100})
      
      查询x等于100,y等于99的
      db.jerry_collection.find({x:100,y:99})
      
    • 比较运算符:{字段:{$gte:值}}
      l:less g:great e:equal
      小于:{$lt:值}
      小于等于:{$lte:值}
      大于:{$gt:值}
      大于等于:{$gte:值}
      
      # 查询y大于等于18的数据
      db.jerryn_collection.find({y:{$gte:18}})
      
    • 范围运算符:{字段: {$in:[start,end]}} 反集 $nin
      # 用$in,$nin判断是否在某个范围内查询年龄为18、28的学生
      db.jerry_collection.find({age:{$in:[18,28]}})
      
    • 逻辑运算符:or:{$or:[子条件1,子条件2]}
      # 查询年龄大于18或性别为false的
      db.jerry_collection.find({$or:[{age:{$gt:18}},{gender:false}]})
      

查询结果操作

  • 将结果格式化:db.集合名称.find().pretty()

  • 求查出的数据条数:db.集合名称.find().count()
    读取指定条数:db.集合名称.find().limit(条数)
    跳过指定条数:db.集合名称.find().skip(2)

  • 指定返回的字段:db.集合名称.find({},{_id:1}) # 如果为1则返回该字段,如果为0则除了改字段外所有字段返回。

  • 排序:db.集合名称.find().sort({age:1}) # 为1升序排序,为-1降序排序

    按照年龄升序排序
    db.jerry_collection().find().sort({age:1})
    
    按照年龄降序排序
    db.jerry_collection().find().sort({age:-1})
    

显示查询操作的详细信息

  • db.集合名称.find({条件}).explain(‘executionStats’) # 显示查询操作的详细信息
  • 可以用来测试查询的性能

查询题目练习

  • 测试数据:链接:https://pan.baidu.com/s/1U4-fQTqPWBQhFGJAgV5RGw
    提取码:1005
    1.查询年龄大于25小于27的name,age
    db.persons.find({age:{$gt:25,$lt:27}},{name:1,age:1})
    2.查询出不是美国的name
    db.persons.find({country:{$ne:'USA'}},{name:1})
    3.查询国籍是中国或者美国的学生信息
    db.persons.find({$or:[{country:'USA'},{country:'China'}]})
    4.查询语文成绩大于85或者英语成绩大于90的学生信息
    db.persons.find({$or:[{c:{$gt:85}},{e:{$gt:90}}]})
    5.查询出名字中存在"li"的学生信息
    db.persons.find({name:/li/},{name:1})
    6.查询喜欢看MONGODB和PHP的学生
    db.persons.find({books:{$all:['MONGODB','PHP']}},{books:1})
    7.查询第二本书是JAVA的学生信息
    db.persons.find({'books.1':'JAVA'},{books:1})
    8.查询喜欢的书数量是4本的学生
    db.persons.find({books:{$size:4}},{books:1})
    9.查询出persons中的国家分别是什么
    db.persons.distinct('country')
    

(四)聚合

  • 聚合是基于数据处理的聚合管道,每个文档通过一个由多个阶段组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果
    在这里插入图片描述

  • 常用表达式:处理输⼊⽂档并输出,语法:表达式:’$列名’

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

    • $group:将集合中的数据分组,可用于统计结果。
    • $match:过滤数据,只输出符合条件的文档。match是管道命令,能将结果交给后一个管道
    • $sort:将输入文档排序后输出
    • $limit:限制聚合管道返回的文档书
    • $skip:跳过指定数量的文档,并返回余下的文档
    '''
    group
    '''
    # _id表示分组的依据,使用某个字段的格式为 '$字段'
    # 按照gender分组
    db.students.aggregate(
    {$group:{_id:'$gender',count:{$sum:1}}}
    )
    # 按照gender分组,获取不同组的平均年龄
    db.students.aggregate(
    {$group:{_id:'$gender',count:{$sum:1},avg_age:{$avg:"$age"}}}
    )
    '''
    match
    '''
    # 查询年龄大于20的学生
    db.students.aggregate(
    {$match:{age:{$gt:20}}}
    )
    # 查询年龄大于20的男生,女生人数
    db.students.aggregate(
    {$match:{age:{$gt:20}}},
    {$group:{_id:'$gender',count:{$sum:1}}}
    )
    

(五)索引

为什么需要创建索引

  • 加快查询速度、进行数据的去重

创建索引

  • 语法:db.集合名.ensureIndex({字段:1}),1表示升序, -1表示降序

查看索引

  • db.集合名.getIndexes()

删除索引

  • 语法:db.集合名.dropIndex({‘索引字段’:1})

三、与python交互----pymongo

pymongo安装

  • pip install pymongo

连接mongodb

  • 方式一:self.lient = MongoClient(‘mongodb://localhost:27017/’)
  • 方式二 :self.client = MongoClient(‘localhost’,27017)

指定连接的数据库/集合

  • 指定数据库:self.db = self.client[‘数据库名’]
  • 指定集合:self.col=self.client[‘数据库名’][‘集合名’]

新增数据

from pymongo import MongoClient
from datetime import datetime

class TestMongo(object):
    def __init__(self):
        self.client = MongoClient('mongodb://localhost:27017/')
        # 也可以指定连接的集合client['admin']['students']
        self.db = self.client['admin']
        # print(self.client.database_names())

    def add_one(self):
        post = {'title':'标题','content':'内容','created_at':datetime.now()}
        # db.students   students 是表明
        res = self.db.students.insert_one(post)
        return res
        
    def add_more(self):
        data_list = [{"name":"test{}".format(i)} for i in range(5)]
        res = self.db.students.insert_many(data_list)
        return res
    

mongo = TestMongo()
res = mongo.add_one()
插入的ID
print(res.inserted_id)

查询数据

from bson.objectid import ObjectId
查询一条数据
def get_one(self):
    return self.db.students.find_one()

查询多条数据
def get_more(self):
    return self.db.students.find()

根据记录的ID查询数据
def get_from_id(self,id):
    return self.db.students.find_one({'_id':ObjectId(id)})

查询一条数据 
res = mongo.get_one()
查询多条数据
res = mongo.get_more()
for i in res:
	print(i)
根据记录的ID查询数据
res = mongo.get_from_id('5b83e8a1b594c32e8c70c1f7')
print(res)

修改数据

修改单条数据
def update(self):
    res = self.db.students.update_one({'title':'标题'},{'$set':{'title':'title-2'}})
    # 匹配的数据条数
    print(res.matched_count)
    # 影响的数据条数。
    print(res.modified_count)

修改多条
def update_more(self):
    res = self.db.students.update_many({},{'$set':{'x':1}})
    print(res.matched_count)
    print(res.modified_count)
    res = self.db.students.update({'x':2},{'$set':{'x':3}},True)
    
res = mongo.update()
res = mongo.update_more()

删除数据

删除一条
def delete_one(self):
    res = self.db.students.delete_one({'title':'title-2'})
    print(res.deleted_count)

删除多条
def delete_more(self):
    res = self.db.students.delete_many({'x':2})
    print(res.deleted_count)
    
res = mongo.delete_one()
res = mongo.delete_more()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洋芋本人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值