非关系型数据库——mongodb

爬虫数据存储相关的数据库MongoDB

关系型数据库
	MySQL、oracle、acess、db2、postgresql、sqlite...
		1.存储数据基本都是以表格为基本形式
    	2.表与表之间可以建立关系(外键)

非关系型数据库
	redis、mongodb、memcache
    	1.数据基本都是以key:value键值对的形式存储
        2.没有明确的表结构限制

"""
主库一般情况下都是关系型数据库
从库一般情况下都是非关系型数据库
	从库一般情况下较于主库数据的存取速度都比较快
"""
持久化
	肯定跟数据库相关
    因为持久化就是用数据库来长期的保存数据

MongoDB简介
	1.是爬虫爬取数据之后首选的一款数据持久化软件
    2.最像关系型数据库的文档型非关系型数据库
1.下载安装的时候
	如果是压缩包的形式,那么解压之后只有一个bin文件夹
    你需要自己创建一个data文件夹和log文件夹
  
2.将mongo.exe和mongod.exe所在的路径添加到环境变量中
	
3.执行以下安装系统服务的命令
	mongod --bind_ip 0.0.0.0 --port 27017 --logpath D:\MongoDB\log\mongod.log --logappend --dbpath D:\MongoDB\data\db  --serviceName "MongoDB" --serviceDisplayName "MongoDB"  --install
    上述命令完成后只会将MongoDB添加到系统服务里面并没有启动
  
4.启动服务
	net start MongoDB  # 手动找到服务启动也可以
 	# 停止服务
    net stop MongoDB
 
5.上述的系统服务制作类似于MySQL以跳过授权表的方式启动服务端
	mysqld --skip-grant-tables
    
    # 如何让mongodb也校验用户名和密码
    先停止服务
    net stop MongoDB
    移除
    mongod --remove
  	重新制作系统服务
    mongod --bind_ip 0.0.0.0 --port 27017 --logpath D:\MongoDB\log\mongod.log --logappend --dbpath D:\MongoDB\data\db  --serviceName "MongoDB" --serviceDisplayName "MongoDB"  --install --auth
    启动系统服务
    net start MongoDB
  
6.MongoDB每一个库都可以创建用户名和密码 并且创建的用户名和密码都是普通用户
	如果你想要创建管理员用户就必须去admin库下创建才可以
	
7.创建管理员用户
	'''涉及到用户登录认证 引号最好统一都用双引号'''
	use admin  # 切换到admin下
    db.createUser(
      {
        user: "root",
        pwd: "123",
        roles: [ { role: "root", db: "admin" } ]
      }
    )

8.让MongoDB以校验用户身份启动
	mongod --bind_ip 0.0.0.0 --port 27017 --logpath D:\MongoDB\Server\4.2\log\mongod.log --logappend --dbpath D:\MongoDB\Server\4.2\data  --serviceName "MongoDB" --serviceDisplayName "MongoDB"  --install --auth
            
    net start MonoDB
    
    mongo进入服务端之后发现没有很多权限
    需要验证身份
    	这个用户在哪个库下面创建的就必须切换到哪个库下面去做验证
         
9.创建普通用户
	use test
    db.createUser(
      {
        user: "jason",
        pwd: "123",
        roles: [ { role: "readWrite", db: "test" },  
                 { role: "read", db: "db1" } ]  
      }
    )
    # 删除创建的用户
    db.dropUser(username)  # 用户在哪个库下面创建的 之后针对该用户的操作都必须切换到该库下
10.也可以直接使用用户名和密码方式登录
	mongo --port 27017 -u "root" -p "123" --authenticationDatabase "admin"
"""
在mongodb中所有的命令都可以采用.help()的形式查看具体的使用说明
"""     

数据库的增删改查语句

# 查看当前所在的库名
db

# 切换库|增库
# 库不存在直接创建 库存在则切换
use 库名
'''
创建出来的库使用show dbs是无法直接看到的
因为这个库目前里面什么数据都没有 其实是创建在内存中的还没有保存到硬盘上
'''

# 查看所有库
show databases
show dbs

# 删库
# 先切换到该库下 然后删
use 库名
db.dropDatabase()

collections集合操作(表操作)

# 查看当前库中所有的表
show tables

# 增加表
use 库名	# 先进入库
db.表名.insert({'a':1,'b':2})  # 表不存在会自动创建,insert就是往表中添加数据
db.表名.insert({'a':111,'b':222,'c':333})  # 键值对的个数每次都可以不一样

# 删除表
db.表名.drop()

document文档操作(记录操作)

# 插入单条 insert({})
t10={"name":"a","age":10,'hobbies':['music','read','dancing']}
db.t1.insert(t10)
db.t1.find()

# 插入多条 insertMany([{},{},{},{}])
t11={"_id":1,"name":"a","age":10,'hobbies':['music','read','dancing']}
t12={"_id":2,"name":"b","age":20,'hobbies':['music','read','run']}
t13={"_id":3,"name":"c","age":30,'hobbies':['music','drink']}
t14={"_id":4,"name":"d","age":40,'hobbies':['music','read','dancing','tea']}
t15={"_id":5,"name":"e","age":50,'hobbies':['music','read',]}
db.t1.insertMany([t11,t12,t13,t14,t15])
db.t1.find()

db.表名.find()  # 查询当前表中所有的数据
findOne()  # 只拿匹配到的第一个数据
"""
mongoDB会自动给每个数据项添加一个主键字段
_id: ObjectId('23432h234j24234j')  # 自动创建的唯一编号

如果你自己给了_id字段 那么则不会再自动创建了
"""
db.表名.find({'a':1})  # 查询含有a:1键值对的数据


# 详细操作
#1、查看既有dancing爱好又有tea爱好的人
# $all类似于是and关系
db.t1.find({'hobbies':{"$all":['dancing','tea']}})

#2、查看第4个爱好为tea的人(索引为依据)
db.t1.find({"hobbies.3":'tea'})

#3、查看所有人的第2个到第3个爱好
db.t1.find({},{'hobbies':{"$slice":[1,2]},"age":0,"_id":0,"name":0,"addr":0})
# 键后面的值是0表示查询的时候不要这些键对应的数据

#4、将数据以标准的格式展示出来
db.t1.find().pretty()

#5、取指定的字段数据
#SQL:select name,age from db.t1 where id=3;
db.t1.find({'_id':3},{'_id':0,'name':1,'age':1})
运算符
# SQL:=,!=,>,<,>=,<=
# MongoDB:{key:value}代表什么等于什么,"$ne","$gt","$lt","gte","lte",其中"$ne"能用于所有数据类型

#1、select * from db1.t1 where name = "a";
db.t1.find({'name':'a'})	# =

#2、select * from db1.t1 where name != "a";
db.t1.find({'name':{"$ne":'a'}})  # $ne : not equal(!=)

#3、select * from db1.t1 where id > 2;	# $gt : >
db.t1.find({'_id':{'$gt':2}})

#4、select * from db1.t1 where id < 3;	# $lt : <
db.t1.find({'_id':{'$lt':3}})

#5、select * from db1.t1 where id >= 2;	# $gte : >=
db.t1.find({"_id":{"$gte":2,}})

#6、select * from db1.t1 where id <= 2;	# $lte : <=
db.t1.find({"_id":{"$lte":2}})
逻辑运算
# SQL:and,or,not
# MongoDB:字典中逗号分隔的多个条件是and关系,"$or"的条件放到[]内,"$not"
# 字段是键 连接符和条件单独放值的字典

#1、select * from db1.t1 where id >= 2 and id < 4;
db.t1.find({'_id':{"$gte":2,"$lt":4}})

#2、select * from db1.t1 where id >= 2 and age < 40;
db.t1.find({"_id":{"$gte":2},"age":{"$lt":40}})

#3、select * from db1.t1 where id >= 5 or name = "a";
db.t1.find({"$or":[{'_id':{"$gte":5}},{"name":"a"}]})

#4、select * from db1.t1 where id % 2=1;
db.t1.find({'_id':{"$mod":[2,1]}})

#5、上题,取反
db.t1.find({'_id':{"$not":{"$mod":[2,1]}}})
成员运算
# SQL:in,not in
# MongoDB:"$in","$nin"

#1、select * from db1.t1 where age in (20,30,31);
db.t1.find({"age":{"$in":[20,30,31]}})

#2、select * from db1.t1 where name not in ('a','b');
db.t1.find({"name":{"$nin":['a','b']}})
正则运算
# SQL: regexp 正则
# MongoDB: /正则表达/i

#1、select * from db1.t1 where name regexp '^a.*?(g|n)$';
db.t1.find({'name':/^a.*?(g|n)$/i})
排序
# sql:asc desc
# 排序:1代表升序,-1代表降序
db.t1.find().sort({"name":1,})
db.t1.find().sort({"age":-1,'_id':1})
限制数据展示条数
# 分页:limit代表取多少个document,skip代表跳过前多少个document。 
# select * from t1 order by age limit(2,1)
db.t1.find().sort({'age':1}).limit(1).skip(2)

# 获取数量
db.t1.count({'age':{"$gt":30}}) 

# 删除多个中的第一个 deleteOne({})
db.t1.deleteOne({'age': 8 })

# 删除所有 deleteMany({})
# 删除所有年龄为8岁的
db.t1.deleteMany({ 'age': 8 })	# SQL:delete from t1 where ...
#3、删除全部
db.t1.deleteMany({})  # SQL:delet from t1;

覆盖式
# update就类似于是将原来的数据完完全全的重新写一份	效率较低
# 注意:除非是删除,否则_id是始终不会变的
db.t1.update({'_id':1},{"name":"z","hobbies_count":3})
# 是用{"_id":1,"name":"z","hobbies_count":3}覆盖原来的记录

'''
你可以将查询出来的一个个数据看成是一个个对象
然后可以利用对象点点点的操作来获取数据和修改数据
'''
var obj=db.t1.findOne({"_id":1})
obj.t1name=obj.name+'!'
delete obj.age
db.t1.update({"_id":1},obj)
设置$set
# $set 哪里需要修改就针对性的改哪里
#1、SQL:update db1.t1 set  name="X" where id = 2
db.t1.update({'_id':2},{"$set":{"name":"X",}})

#2、没有匹配成功则新增一条{"upsert":true}
db.t1.update({'_id':6},{"$set":{"name":"f","age":18}},{"upsert":true})

#3、默认只改匹配成功的第一条,{"multi":改多条}
db.t1.update({'_id':{"$gt":4}},{"$set":{"age":28}})
db.t1.update({'_id':{"$gt":4}},{"$set":{"age":38}},{"multi":true})

'''
看似字典的数据其实是对象
并且这个对象比我们python面向对象里面的对象还要灵活
既可以点键
也可以点索引值
'''
#4、把名字为e的人的第2个爱好改成piao
db.t1.update({'name':"e"},{"$set":{"hobbies.1":"piao"}})

#5、删除e的爱好,$unset
db.t1.update({'name':"e"},{"$unset":{"hobbies":""}})
增加与减少$inc
#1、所有人年龄增加一岁
db.t1.update({},{"$inc":{"age":1}},{"multi":true})

#2、所有人年龄减少5岁
db.t1.update({},{"$inc":{"age":-5}},{"multi":true})
元素的添加删除
#添加删除数组内元素
"""
push  python列表中append
pop   python列表中pop
pull  python列表中remove
$each  后面跟一个列表 类似于python中的for循环
"""
    
# 往数组内添加元素:$push
#1、为名字为c的人添加一个爱好read
db.t1.update({"name":"c"},{"$push":{"hobbies":"read"}})

#2、为名字为c的人一次添加多个爱好tea,dancing
db.t1.update({"name":"c"},{"$push":{
    "hobbies":{"$each":["tea","dancing"]}
}})

# 按照位置且只能从开头或结尾删除元素:$pop
#1、{"$pop":{"key":1}} 从数组末尾删除一个元素
db.t1.update({"name":"c"},{"$pop":{
    "hobbies":1}
})

#2、{"$pop":{"key":-1}} 从头部删除
db.t1.update({"name":"c"},{"$pop":{
    "hobbies":-1}
})

# 按照条件删除元素
# "$pull" 把符合条件的统统删掉,而$pop只能从两端删
db.t1.update({"name":"c"},{"$pull":{
    "hobbies":"read"}},{"multi":true}
重复值添加$addToSet
#避免添加重复:"$addToSet"  # 如果重复就不再添加了

db.urls.insert({"_id":1,"urls":[]})

db.urls.update({"_id":1},{"$addToSet":{"urls":'http://www.baidu.com'}})
db.urls.update({"_id":1},{"$addToSet":{"urls":'http://www.baidu.com'}})
db.urls.update({"_id":1},{"$addToSet":{"urls":'http://www.baidu.com'}})

db.urls.update({"_id":1},{
    "$addToSet":{
        "urls":{
        "$each":[
            'http://www.baidu.com',
            'http://www.baidu.com',
            'http://www.xxxx.com'
            ]
            }
        }
    }
)
posted @ 2020-09-28 18:59  最冷不过冬夜  阅读(246)  评论(0编辑  收藏  举报