八:《智慧的网络爬虫》— MongoDB概述

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
简介: 【8月更文挑战第14天】本篇文章简单介绍了MongoDB的下载和安装以;其基本的操作语法,并附上每个语法的代码示例,为后续的爬虫学习打下基础

一:为什么要使用nosql

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

(1)Nosql简介

  • NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。
  • NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。

(2)发展现状

  • 现今的计算机体系结构在数据存储方面要求应用架构具备庞大的水平扩展性,而NoSQL正在致力于改变这一现状。目前新浪微博的 RedisGoogleBigtable 以及 AmazonSimpleDB使用的就是 NoSQL 型数据库。
  • NoSQL 项目的名字上看不出什么相同之处,但是,它们通常在某些方面相同:它们可以处理超大量的数据。
  • 这场革命目前仍然需要等待。NoSQL 对大型企业来说还不是主流,但是,一两年之后很可能就会变个样子。在 NoSQL 运动的最新一次聚会中,来自世界各地的 150 人挤满了 CBS Interactive 的一间会议室。分享他们如何推翻缓慢而昂贵的关系数据库的暴政,怎样使用更有效和更便宜的方法来管理数据。
  • 关系型数据库给你强加了太多东西。它们要你强行修改对象数据,以满足数据库系统的需要。在 NoSQL 拥护者们来看,基于 NoSQL 的数据库替代方案“只是给你所需要的”

(3)Nosql特点

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

集群扩充起来非常方便并且成本很低,避免了传统商业数据库“sharding”操作的复杂性和成本。

  1. 它击碎了性能瓶颈

NoSQL 的支持者称,通过 NoSQL 架构可以省去将 WebJava 应用和数据转换成 SQL 格式的时间,执行速度变得更快。“SQL并非适用于所有的程序代码”,对于那些繁重的重复操作的数据,SQL 值得花钱。但是当数据库结构非常简单时,SQL 可能没有太大用处

  1. 它没有过多的操作

虽然 NoSQL 的支持者也承认关系型数据库提供了无可比拟的功能集合,而且在数据完整性上也发挥绝对稳定,他们同时也表示,企业的具体需求可能没有那么复杂

  1. 它的支持者源于社区
  • 因为 NoSQL 项目都是开源的,因此它们缺乏供应商提供的正式支持。这一点它们与大多数开源项目一样,不得不从社区中寻求支持

(4)MongoDB特点

  • 面向集合(Collenction-Orented

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

  • 模式自由(schema-free)

    意味着对于存储在 MongoDB 数据库中的文件,我们不需要知道它的任何结构定义。提了这么多次"无模式"或"模式自由",它到是个什么概念呢?例如,下面两个记录可以存在于同一个集合里面: {"welcome" : "Beijing"} {"age" : 25}

  • 文档型

    意思是我们存储的数据是键-值对的集合,键是字符串,值可以是数据类型集合里的任意类型,包括数组和文档. 我们把这个数据格式称作 “BSON” 即 “Binary Serialized document Notation.”

二:MongoDB下载与安装

1.MongoDB官网

2.启动MongoDB

终端命令:mongod --dbpath C:\Program Files\MongoDB\Server\4.4\data img

3.连接MongoDB

  • 在环境变量设置好的前提下,在终端输入命令mongo就可以进入到mongo的操作终端了。

配置环境变量参考如下: https://blog.csdn.net/Alisa_Sheng/article/details/122621415

  • 图例所示:img

三:MongoDB解析

mongodb中基本的概念是文档、集合、数据库。下表将帮助您更容易理解Mongo中的一些概念: img

1.MongoDB三要素

  • 数据库:一个集合的物理容器,一个数据库可以包含多个文档(一个服务器通常有多个数据库)。
  • 文档:就是关系型数据库中的一行。文档是一个对象,由键值对构成,是json的扩展形式
  • 集合:类似于关系型数据库中的表,集合存在于数据库中,集合没有固定的结构,这意味着你在对集合可以插入不同格式和类型的数据,但通常情况下我们插入集合的数据都会有一定的关联性。

2.MongoDB数据类型

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

3.MongoDB操作数据库的常用命令(了解)

  • show dbs 查看所有数据库

img

  • db:查看现在用的数据库 (MongoDB 中默认的数据库为 test,如果你没有创建新的数据库,集合将存放在 test 数据库中)

img

  • cls:清屏的命令
  • use admin:如果数据库不存在,则创建数据库,否则切换到指定数据库

img img

  • db.dropDatabase():要删除某个数据库,需要切换到该数据库通过usedb进行切换

img

4.MongoDB创建集合与查看集合

  • 手动创建集合之不带关键字创建

img

  • 手动创建集合之带关键字创建集合

关键字参数用法: img img

  • 自动创建集合
  • MongoDB 中,你不需要创建集合。当你插入一些文档时,MongoDB 会自动创建集合

img

5.MongoDB删除集合

img

6.MongoDB插入文档(就是在集合/表中插入数据)

  • insert插入单条数据

img

  • insert插入多条数据
for(i=3;i<10;i++)db.test01.insert({x:i})

img img

  • 参数说明:BulkWriteResult.writeErrors

文档数组,其中包含有关更新操作期间遇到的与写入问题无关的任何错误的信息。该writeErrors数组包含每个错误的写入操作的错误文档。

  - **BulkWriteResult.writeConcernError**

描述与写关注有关的错误的文档

  - **BulkWriteResult.nInserted**

使用该Bulk.insert() 方法插入的文档数,对于通过带Bulk.find.upsert()选项的操作插入的文档

  - **BulkWriteResult.nUpserted**

通过带Bulk.find.upsert()选项的操作插入的文档数

  - **BulkWriteResult.nMatched**

选择用于更新或替换的现有文档数。如果更新/替换操作未更改现有文档

  - **BulkWriteResult.nModified**

已更新或替换的现有文档数。如果更新/替换操作未更改现有文档

  - **BulkWriteResult.nRemoved**

删除的文件数

  - **BulkWriteResult.upserted**

文档数组,包含有关通过带Bulk.find.upsert() 选项的操作插入的每个文档的信息

7.MongoDB查询数据

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.stu.find():查询数据/可以在括号里面精确查找

img

  • db.stu.find().pretty():格式化文档打印

img

  • db.stu.find({name:'jerry'}).pretty():精确查找并格式化打印

img

  • db.stu.findOne():格式化打印第一条查询的数据

img

  • db.stu.find({age:18})

img

  • db.stu.findOne({age:18}):把满足结果的第一条数据进行返回

img

  • db.stu.find({age:18,gender:true}):在find中进行多条件查询

img

  • 查询之比较运算符

    1. 等于:默认是等于判断,没有运算符
    2. 小于:$lt
    3. 小于等于:$lte
    4. 大于:$gt
    5. 大于等于:$gte

    查询年龄大于18的元素:db.stu.find({age:{$gt:18}})

img

  - 查询年龄大于18的元素且hometown是长沙的元素
     - db.stu.find({age:{$gt:18},hometown:"长沙"})

img

  • 查询之范围运算符:使用$in,$nin判断是否在某个范围内

    查询年龄为18和年龄28的学生:

img

  • 查询之逻辑运算符
    1. or:使用$or,值为数组,数组中每个元素为json
    2. 查询年龄大于18或者genderflase
    3. db.stu.find({$or:[{age:{$gt:18}},{gender:false}]})

img

  • 查询之自定义查询

    查询年龄大于18的学生:db.stu.find({$where:function(){return this.age>18}})

img

8.MongoDB操作查询数据

  • count:查出数据求总和 也可以精确查找想要的总和

img

  • limit:用于读取指定数量的文档

img

  • skip:用于跳过指定数量的文档

img

  • limitskip同时使用

img

  • 映射:指定返回的字段,如果为1则返回该字段 如果为0则除了该字段外所有字段返回,id如果没写会默认返回

img

  • id去除

img

  • 映射多个值:比如只要年龄和性别不去除id

img

  • 排序

    升序
    

img

  - 降序

img

  - 根据find()精确查找然后进行排序

img

9.MongoDB更新文档

  • db.集合名称.update({query}, {update}, {multi: boolean})
    • 参数query:查询条件
    • 参数update:更新操作符
    • 参数multi:可选,默认是false,表示只更新找到的第一条数据,值为true表示把满足条件的数据全部更新
  • db.stu.update({name:'jerry'},{name:'杰瑞'}),这种情况下会改变name但是其他的会被删除

img

  • db.stu.update({name:'张三'},{$set:{name:'张三丰'}})这种情况下会改变name且其他的信息不会变化

img

  • 更新多条:比如说将所有的gender变成0,此时会发现 如果没有gender这个属性会进行添加

img

10.MongoDB删除文档

  • remove() 方法的基本语法
    1. db.collection.remove(<query>, <justOne> )
    2. query:删除的文档的条件。
    3. justOne:如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
  • 删除符合条件的第一条数据

img

  • 删除符合条件的多条数据

img

  • 删除表/集合

    语法: db.集合名.drop()

img

四:MongoDB练习

(1)测试数据

var persons = [{
        name:"jim",
        age:25,
        email:"75431457@qq.com",
        c:89,m:96,e:87,
        country:"USA",
        books:["JS","C++","EXTJS","MONGODB"]
},
{
        name:"tom",
        age:25,
        email:"214557457@qq.com",
        c:75,m:66,e:97,
        country:"USA",
        books:["PHP","JAVA","EXTJS","C++"]
},
{
        name:"lili",
        age:26,
        email:"344521457@qq.com",
        c:75,m:63,e:97,
        country:"USA",
        books:["JS","JAVA","C#","MONGODB"]
},
{
        name:"zhangsan",
        age:27,
        email:"2145567457@qq.com",
        c:89,m:86,e:67,
        country:"China",
        books:["JS","JAVA","EXTJS","MONGODB"]
},
{
        name:"lisi",
        age:26,
        email:"274521457@qq.com",
        c:53,m:96,e:83,
        country:"China",
        books:["JS","C#","PHP","MONGODB"]
},
{
        name:"wangwu",
        age:27,
        email:"65621457@qq.com",
        c:45,m:65,e:99,
        country:"China",
        books:["JS","JAVA","C++","MONGODB"]
},
{
        name:"zhaoliu",
        age:27,
        email:"214521457@qq.com",
        c:99,m:96,e:97,
        country:"China",
        books:["JS","JAVA","EXTJS","PHP"]
},
{
        name:"piaoyingjun",
        age:26,
        email:"piaoyingjun@uspcat.com",
        c:39,m:54,e:53,
        country:"Korea",
        books:["JS","C#","EXTJS","MONGODB"]
},
{
        name:"lizhenxian",
        age:27,
        email:"lizhenxian@uspcat.com",
        c:35,m:56,e:47,
        country:"Korea",
        books:["JS","JAVA","EXTJS","MONGODB"]
},
{
        name:"lixiaoli",
        age:21,
        email:"lixiaoli@uspcat.com",
        c:36,m:86,e:32,
        country:"Korea",
        books:["JS","JAVA","PHP","MONGODB"]
},
{
        name:"zhangsuying",
        age:22,
        email:"zhangsuying@uspcat.com",
        c:45,m:63,e:77,
        country:"Korea",
        books:["JS","JAVA","C#","MONGODB"]
}]

for(var i = 0;i<persons.length;i++){
        db.persons.insert(persons[i])
}

var persons = db.persons.find({name:"jim"})
while(persons.hasNext()){
        obj = persons.next();
        print(obj.books.length)
}

(2)练习

1.查询年龄大于25小于27的name,age
db.persons.find({age:{$gt:25,$lt:27}})

2.查询出不是美国的name
db.persons.find({country:{$ne:'USA'}})
db.persons.find({country:{$ne:'USA'}},{name:1})
db.persons.find({country:{$ne:'USA'}},{name:1,country:1})

3.查询国籍是中国或者美国的学生信息
db.persons.find({$or:[{country:'USA'},{country:'China'}]})
db.persons.find({$or:[{country:'USA'},{country:'China'}]},{country:1}) 数据有点多映射国家

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})
db.persons.find({books:{$all:['MONGODB','PHP']}},{books:1,name:1})


7.查询第二本书是JAVA的学生信息
db.persons.find({},{books:1})
db.persons.find({'books.1':'JAVA'},{name:1,books:1})  'books.1'代表的是索引

8.查询喜欢的书数量是4本的学生
db.persons.find({books:{$size:4}},{books:1})

9.查询出persons中一共有多少国家分别是什么
db.persons.find({},{country:1})
db.persons.distinct('country')

五:MongoDB创建索引

测试数据集

for(i=0;i<100000;i++){db.test.insert({name:'test'+i,age:i})}

为什么要用到索引 ?

  • 索引通常能够极大的提高查询的效率,如果没有索引,MongoDB在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录。
  • 这种扫描全集合的查询效率是非常低的,特别在处理大量的数据时,查询可以要花费几十秒甚至几分钟,这对网站的性能是非常致命的。
  • 索引是特殊的数据结构,索引存储在一个易于遍历读取的数据集合中,索引是对数据库表中一列或多列的值进行排序的一种结构

(1)创建索引前

db.test.find({name:'test9999'})
db.test.find({name:'test9999'}).explain('executionStats') # 显示查询操作的详细信息

 "executionTimeMillis" : 39, 测试结果  "executionTimeMillis" : 37, 这个结果不唯一

(2)怎么去创建索引

db.test.ensureIndex({name:1})

(3)创建索引后

db.test.find({name:'test9999'}).explain('executionStats')

"executionTimeMillis" : 6, 测试结果 
"executionTimeMillis" : 0,

(4)查看所有的索引

db.test.getIndexes()
默认情况下_id是集合的索引

(5)删除索引

语法:db.集合名.dropIndex({'索引名称':1})
db.test.dropIndex({name:1})
db.test.getIndexes()

注意:

在 3.0.0 版本前创建索引方法为 db.collection.ensureIndex(),之后的版本使用了 db.collection.createIndex() 方法,ensureIndex() 还能用,但只是 createIndex() 的别名。

拓展: 关于mongodb资料参考:https://www.runoob.com/mongodb/mongodb-indexing.html

六:pythonMongoDB交互(掌握插入)

(1)数据库的连接

from pymongo import MongoClient
# 连接
client = MongoClient()

(2)MongoDB交互的增删改查

import pymongo
from pymongo import MongoClient

class Mongo_python:
    # 初始化方法
    def __init__(self, HOST, PORT):
        self.HOST = HOST
        self.PORT = PORT
        # 连接
        self.client = MongoClient(HOST, PORT)

    # 插入数据
    def insert_data(self):
        # 插入单条数据
        # self.client.school.teacher.insert_one({"name": "李璐2", "role": "兼职老师"})
        # 插入多条数据
        self.client.school.teacher.insert_many([{
   "name": "晨刚"}, {
   "name": "郭丽丽"}])

    # 查询数据
    def query_data(self):
        try:
            teachers = self.client.school.teacher.find()
            # print(list(teachers),type(teachers))
            # for one in teachers:
            #     print("查找多条数据:", one["_id"], one["name"])

            teacher = self.client.school.teacher.find_one({
   "name": "李璐2"})
            print("查找单条数据:", teacher["_id"], teacher["name"])
        except Exception as e:
            print(e)

    # 修改数据
    def set_data(self):
        # 修改多条数据
        # self.client.school.teacher.update_many(
        #     {}, {"$set": {"role": "班主任11111"}}
        #
        # )
        # 修改单条数据
        # self.client.school.teacher.update_one({"name": "晨刚"}, {"$set": {"sex": "女"}})
        # push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。
        self.client.school.teacher.update_one({
   "name": "晨刚"}, {
   "$push": {
   "sdarole": "年级主任"}})

    # 删除数据
    def delete_data(self):
        try:
            # 删除单条数据
            # self.client.school.teacher.delete_one({"name": "晨刚"})
            # 删除多条数据
            # 第一个参数是一个查询对象,用于定义要删除的文档
           query = {
   "name": '李璐2'}
           self.client.school.teacher.delete_many(query)
        except Exception as e:
            print(e)


if __name__ == '__main__':
    mg = Mongo_python('localhost', 27017)
    # mg.insert_data()
    # mg.query_data()
    # mg.set_data()
    mg.delete_data()
相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
29天前
|
人工智能 自然语言处理 NoSQL
|
1月前
|
机器学习/深度学习 存储 自然语言处理
深度学习入门:循环神经网络------RNN概述,词嵌入层,循环网络层及案例实践!(万字详解!)
深度学习入门:循环神经网络------RNN概述,词嵌入层,循环网络层及案例实践!(万字详解!)
|
1月前
|
机器学习/深度学习 PyTorch API
深度学习入门:卷积神经网络 | CNN概述,图像基础知识,卷积层,池化层(超详解!!!)
深度学习入门:卷积神经网络 | CNN概述,图像基础知识,卷积层,池化层(超详解!!!)
|
3月前
|
存储 网络协议 安全
|
2月前
|
存储 NoSQL MongoDB
01 MongoDB的概述、应用场景、下载方式、连接方式和发展历史等
文章详细介绍了MongoDB的概览、应用场景、下载与连接方式,并涵盖了MongoDB的主要特性及其在数据存储方面的优势。
28 0
|
3月前
|
数据采集 移动开发 Python
六:《智慧的网络爬虫》— 正则表达式概述
【8月更文挑战第7天】本文介绍了正则表达式的基本概念、用途,如表单验证和爬虫,以及Python中re模块的使用,包括match(),match()函数、元字符、预定义字符集、重复匹配、位置匹配、非贪婪模式和re模块的常用方法如compile(),search(),findall(),split(),sub()等。
73 1
六:《智慧的网络爬虫》— 正则表达式概述
|
2月前
|
Linux 调度 Docker
容器网络概述
【9月更文挑战第9天】容器技术利用如命名空间(namespace)和控制组(cgroup)等技术创建隔离环境,实现资源限制与独立运行。命名空间避免命名冲突,cgroup则能对CPU、内存等资源进行限制。容器状态可通过镜像保存并标准化,确保在任何环境中都能复现相同状态。
|
3月前
|
SQL 数据采集 关系型数据库
七:《智慧的网络爬虫》— MySQL概述
【8月更文挑战第11天】本篇文章详细的介绍了MySQL数据库的安装与使用;并讲述了MySQL的基本操作及其应用语法
50 0
七:《智慧的网络爬虫》— MySQL概述
|
3月前
|
Linux 调度 Docker
容器网络概述
【8月更文挑战第7天】容器就是 Container,而 Container 的另一个意思是集装箱。其实容器的思想就是要变成软件交付的集装箱。集装箱的特点,一是打包,二是标准。
|
3月前
|
存储 运维 监控