python Scrapy进阶(MongoDB)

本文详细介绍了MongoDB的使用,包括其简介、安装、数据库命名规范、主要概念如文档、数据类型,以及如何启动和连接MongoDB。此外,文章还深入探讨了MongoDB的基本操作,如条件操作符、数据的插入、查询、修改和删除,以及聚合操作。最后,文章讲解了如何在Python中使用pymongo模块与MongoDB交互,并展示了如何在Scrapy爬虫项目中配置和使用MongoDB.

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MongoDB

简介

  • MongoDB —— 非关系型数据库(像关系型数据库的非关系型数据库),数据类型灵活
  • 优势
    1. 无数据结构限制,业务开发方便快捷
    2. 大数据量和高性能 —— 读写性能高
    3. 良好的支持 —— 支持跨平台安装

安装

  • 下载地址:https://www.mongodb.com/download-center/community
  • 安装 —— 教程:https://www.cnblogs.com/chy18883701161/p/11100560.html
    • 必须有data和log文件夹
    • 将MongoDB下的bin文件夹添加到环境变量

MongoDB的使用

数据库命名规范

  1. 不能为空的字符串
  2. 不能含有特殊字符
  3. 全部小写
  4. 不能和系统保留的数据库重名
  5. 最多64个字节

MongoDB中的概念

SQL术语/概念MongoDB术语/概念解释/说明
databasedatabase数据库
tablecollection数据库表/集合
rowdocument数据记录行/文档
columnfield字段/域
indexindex索引
primary keyprimary key主键
文档
  • 概念 —— 是由字段和值对组成(结构为:{field1:value1,field2:value2,…})
  • 值的数据类型 —— 包括其他文档、数组和文档数组
# 以下文档包含各种类型的值
{
   _id: ObjectId("5099803df3f4948bd2f98391"),
   name: { first: "Alan", last: "Turing" },
   birth: new Date('Jun 23, 1912'),
   death: new Date('Jun 07, 1954'),
   contribs: [ "Turing machine", "Turing test", "Turingery" ],
   views : NumberLong(1250000)
}

MongoDB的数据类型

数据类型描述
String字符串。存储数据常用的数据类型,在MongoDB中,UTF-8编码的字符串才是合法的
Integer整型数值。用于存储数值。根据采用的服务器,可分为32位或64位
Boolean布尔值。用于存储布尔值
Double双精度浮点值。用于存储浮点值
Min/Max keys将一个值与BSON(二进制的JSON)元素的最低值和最高值相对比
Array用于将数组或列表或多个值存为一个键
Timestamp时间戳。记录文档修改或添加的具体时间
Object用于内嵌文档
Null用于创建空值
Symbol符号。该数据类型基本上等同于字符串类型,但不同的是它一般用于采用特殊符号类型的语言
Date日期时间。用UNIX时间格式来存储当前日期或时间。可以指定自己的日期时间:创建Date对象,传入年月日信息
Object ID对象ID。用于创建文档的ID
Binary Data二进制数据。用于存储二进制数据
Code代码类型。用于在文档中存储JavaScript代码
Regular expression正则表达式类型。用于存储正则表达式

启动和连接MongoDB

  • 启动:mongod --dbpath path # path必须到data文件夹
  • 连接:mongo # 新打开命令提示符窗口

基本使用

常用命令含义
show dbs查看数据库(自带3个数据库尽量不要使用:admin,config,local)
use 数据库名选择使用的数据库,如果database没有则创建database的数据库
db查看当前使用的数据库
show collections/table查看集合/表
db.dropDatabase()删除当前选择的数据库
条件操作符
条件操作符含义
$gt大于符号
$lt小于符号
$gte大于等于符号
$lte小于等于符号
$ne不等于符号
$eq等于符号
$ifNull判断null
$in范围运算符,包含的意思,值为数组
$nin范围运算符,不包含的意思,值为数组
$all范围运算符,匹配所有,值为数组
$or逻辑运算符,或的逻辑,值为数组
$and逻辑运算符,与的逻辑,值为数组
$not逻辑运算符,非得逻辑,值为数组
$concat字符串连接操作
$substr字符串截取操作
$toLower字符串转小写操作
$toUpper字符串转大写操作
$size数组元素个数计算,值为数字
/value/模糊查询,根据value进行模糊查询
$exists判断字段是否存在
$regex正则表达式匹配
$占位符
集合/表的创建、删除和查询
  • MongoDB分为手动和自动建表
    • 自动建表 —— 向一个不存在的集合插入数据,这个集合就会被创建出来
常用命令含义
db.集合名.insert(文档)向表插入数据,数据为{}里的内容。如果集合不存在则创建collectionname的集合再插入数据
db.createCollection(name,{options})创建集合。name是集合名;options为可选参数(指定内存大小及索引的选项),options的参数capped默认值为false表示不设置上限,值为true表示设置上限;当capped为true时,options的参数size必须填写,表示上限大小(mongo中上限小于256则默认为256),当文档达到上限时会覆盖数据,单位为字节
db.集合名.find()查找表内所有数据
db.集合名.isCapped()查看表是否设置上限,如果为false则没有上限,如果为true则有上限
db.集合名.drop()删除表
插入数据
常用命令含义
db.集合名.insert([文档1,文档2…])向表内插入Array类型数据,数据库中显示为多条数据
db.集合名.save(文档1,文档2…)更新数据。当数据中有id时,根据id进行数据更新;当数据中没有id或id不存在时插入数据
查询数据
常用命令含义
db.集合名.find(文档).pretty()查询集合中所有数据,文档为可选条件,如果添加文档则查询集合中符合文档的所有数据。pretty为可选方法,作用为格式化数据(使数据更清晰)
db.集合名.findOne(文档)查询集合中第一个数据。文档为可选条件,如果添加文档则查询集合中第一次出现文档的数据
db.集合名.find(‘array.number’:value)数组内查询时,array.number为array的索引值,根据索引值查找数据
db.集合名.find({array:{$size:number}})数组内查询时,查找数组数量为number的数据
db.集合名.find({‘array.field’:value})数组内查询时,查询数组内文档的数据
db.集合名.find({array:{$elemMatch:query1,query2,…})数组内查询时,数组中至少一个array的值满足所有条件
db.集合名.find({field:value},{array:{$slice:count}}返回指定位置的数组元素值的子集,当count为1时显示数组内第一条数据;当count为-1时显示数组内最后一条数据;当count为索引范围时([number1,number2])显示数组内第number1到number2-1条数据,number1从0开始
db.集合名.distinct(field,query)获取集合中指定字段的不重复值,并以数组的形式返回。field参数为指定返回的字段,query是可选参数为文档查询条件
db.hehe.find({age:{$lt:20})
# { "_id" : ObjectId("604effcf7366bfe03cc172a3"), "name" : "haha", "age" : 18, "gender" : "male" }
# { "_id" : ObjectId("604f00e87366bfe03cc172a6"), "name" : "李四", "age" : 16, "gender" : "male" }
db.hehe.find({age:{$lte:20},gender:'female'})
# { "_id" : ObjectId("604f00b87366bfe03cc172a4"), "name" : "heihei", "age" : 20, "gender" : "female" }
db.hehe.find({age:{$in:[16,20]}}) # age为16和20
# { "_id" : ObjectId("604f00b87366bfe03cc172a4"), "name" : "heihei", "age" : 20, "gender" : "female" }
# { "_id" : ObjectId("604f00e87366bfe03cc172a6"), "name" : "李四", "age" : 16, "gender" : "male" }
db.hehe.find({age:{$nin:[16,20]}}) # age不为16和20
# { "_id" : ObjectId("604effcf7366bfe03cc172a3"), "name" : "haha", "age" : 18, "gender" : "male" }
# { "_id" : ObjectId("604f00db7366bfe03cc172a5"), "name" : "张三", "age" : 34, "gender" : "male" }
# { "_id" : ObjectId("604f00f97366bfe03cc172a7"), "name" : "王二", "age" : 54, "gender" : "female" }
db.hehe.find({$or:[{age:{$lt:18}},{gender:'female'}]}) # 年龄小于18或gender为female
# { "_id" : ObjectId("604f00b87366bfe03cc172a4"), "name" : "heihei", "age" : 20, "gender" : "female" }
# { "_id" : ObjectId("604f00e87366bfe03cc172a6"), "name" : "李四", "age" : 16, "gender" : "male" }
# { "_id" : ObjectId("604f00f97366bfe03cc172a7"), "name" : "王二", "age" : 54, "gender" : "female" }
db.hehe.find({$where:function(){return this.age<18}}) # 查询年龄小于18的数据
操作查询结果
方法使用方法含义
count()db.集合名.find(文档).count()或db.集合名.count(文档)查询结果计数
limit(number)db.集合名.find(文档).limit(number)读取指定数量的文档
skip(number)db.集合名.find(文档).skip(number)跳过指定数量的文档
skip(number).limit(number)db.集合名.find(文档).skip(number).limit(number)跳过指定数量的文档后读取指定数量的文档
sort({field:1})/sort({field:-1})db.集合名.find(文档).sort({field:1})或db.集合名.find(文档).sort({field:-1})排序。sort内field值为1时是升序(由小到大);sort内field值为-1时是降序(由大到小)
映射
  • 指定返回的字段,如果为1则返回该字段,如果为0则返回除了该字段外的所有字段。ID如果没写会默认返回
  • 方法:db.集合名.find({文档},{field:1,field:0,…})
修改数据
  • 第一方法:db.集合名.update({query},{update},{multi:boolean})
    • query参数 —— 查询条件
    • update参数 —— 更新操作符(默认修改整条数据,{$set:{文档}}为修改指定数据,其他数据保留)
    • multi参数 —— 可选参数,默认为false,表示只更新找到的第一条数据;如果值为true,则把满足条件的数据全部更新
db.hehe.update({name:'haha'},{name:'abc'})	# 将原数据指定内容更新,并将原数据其他内容删除
# { "_id" : ObjectId("604effcf7366bfe03cc172a3"), "name" : "abc" }
db.hehe.update({name:'heihei'},{$set:{name:'xyz'}})	#修改指定数据,并保留其他数据
# { "_id" : ObjectId("604f00b87366bfe03cc172a4"), "name" : "xyz", "age" : 20, "gender" : "female" }
  • 第二方法:插入数据内容里的save()方法
删除数据
  • 方法:db.集合名.remove({query},{justOne:true})
    • query参数 —— 可选参数。如果有参数,则删除文档的条件;如果没有参数则删除集合内所有数据
    • justOne参数 —— 可选参数。如果为true或1,则只删除1个数据,如果不设置或使用默认值false,则删除所有匹配条件的数据
聚合
  • 概念 —— 处理数据(如求和,平均值等),并放回计算后的结果
  • 方法:db.集合名.aggregate([管道])
    聚合管道
管道
  • 概念 —— 用于将当前命令的输出结果作为下一个命令的参数(可多管道同时使用)
常用管道符使用方法含义
$porject{$project:普通列,_id列,条件过滤列}控制数据列的显示规则。普通列({field:1/true})表示要显示的内容;_id列({‘_id’:0/false})表示_id是否显示;条件过滤列({field:表达式})为满足表达式之后的数据可以进行显示
$match{$match:条件过滤列}用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作
$limit{$limit:number}用于限制MongoDB聚合管道返回的文档数
$skip{$skip:number}用于在聚合管道中跳过指定数量的文档,并返回余下的文档
$unwind{$unwind:field}将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值
$group{$group:{_id: expression,field1:{accumulator1:expression1},…}}将结合中的文档分组,可用于统计结果。_id强制必须存在,可以为null
$sort{$sort:{field:number}}将输入文档排序后输出(1为从小到大,-1为从大到小)
算数表达式运算符
常用符号使用方法含义
$sumdb.集合名.aggregate([{$group:{_id:"$by_user",num_tutorial:{$sum:expression}}}])求和计算,$sum:1表示以一倍计数
$avgdb.集合名.aggregate([{$group:{_id:"$by_user",num_tutorial:{$avg:expression}}}])计算平均值
$absdb.集合名.aggregate([{$group:{_id:"$by_user",num_tutorial:{$abs:number}}}])求绝对值
$adddb.集合名.aggregate([{$project:{num_tutorial:{$add:[expression]}}}])将数字加在一起或添加数字和日期。如果参数之一是日期,则将其他参数视为要添加到该日期的毫秒数
$mindb.集合名.aggregate([{$group:{_id:"$by_user",num_tutorial:{$min:"$likes"}}}])获取集合中所有文档对应值的最小值
$maxdb.集合名.aggregate([{$group:{_id:"$by_user",num_tutorial:{$max:"$likes"}}}])获取集合中所有文档对应值的最大值
$pushdb.集合名.aggregate([{$group:{_id:"$by_user",url:{$push:"$url"}}}])在结果文档中插入值到一个数组中
$addToSetdb.集合名.aggregate([{$group:{_id:"$by_user",url:{$addToSet:"$url"}}}])在结果文档中插入值到一个数组中,但不创建副本
$firstdb.集合名.aggregate([{$group:{_id:"$by_user",first_url:{$first:"$url"}}}])根据资源文档的排序获取第一个文档数据
$lastdb.集合名.aggregate([{$group:{_id:"$by_user",first_url:{$first:"$url"}}}])根据资源文档的排序获取最后一个文档数据
MongoDB索引操作
  • 功能 —— 极大提高查询效率
查看索引
  • 方法:db.集合名.getIndexes()
创建索引
  • 方法一:db.集合名.ensureIndex(keys) —— MongoDB 3.0被废弃,改用createIndex

    • keys参数为要创建索引的字段(可使用多个字段创建),1为指定按升序创建索引,-1为指定按降序来创建索引
  • 方法二:db.集合名.createIndex(keys,options)

    • keys参数为要创建索引的字段(可使用多个字段创建),1为指定按升序创建索引,-1为指定按降序来创建索引
    • options参数为可选参数,具体参数如下:
    参数类型含义
    background布尔值创建索引会阻塞其他数据库操作,background可指定以后台方式创建索引,即增加background可选参数。默认为false
    unique布尔值建立的索引是否唯一。指定为true创建唯一索引,默认为false
    name字符串索引的名称。如果未指定,MongoDB通过连接索引的字段名和排序顺序生成一个索引名称
    sparse布尔值对文档中不存在的字段数据不启用索引。如果设置为true,在索引字段中不会查询出不包含对应字段的文档,默认为false
    expireAfterSeconds整数型指定一个以秒为单位的数值,完成TTL设定,设定集合的生存时间
    v索引的版本号。默认索引版本取决于mongod创建索引时运行的版本
    weights文档型索引权重值,数值在1至99999之间,表示该索引相对于其他索引字段的得分权重
    default_language字符串对于文本索引,该参数决定了停用词及词干和词器的规则的列表。默认为英语
    language_override字符串对于文本索引,该参数指定了包含在文档中的字段名,语言覆盖默认的language,默认值为language
删除索引
  • 方法:db.集合名.dropIndex(keys)

python与MongoDB交互

  • 安装模块 —— pip install pymongo
  • 导入模块 —— import pymongo
  • 连接MongoDB —— pymongo.MongoClient()
  • 使用类进行增删改查(必须使用cmd连接MongoDB)

Scrapy与MongoDB交互

settings文件添加MongoDB相关内容

  • 添加host —— MONGODB_HOST
  • 添加port —— MONGODB_PORT
  • 添加数据库 —— MONGODB_DATABASENAME
  • 添加集合 —— MONGODB_COLLECTIONNAME

修改pipelines文件

  • MyspiderPipeline内添加init方法
    • 连接MongoDB
    • 指定数据库和集合
  • process_item方法内向MongoDB插入数据
    • 将item参数转换为字典(dict(item))
    • insert(data)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值