文章目录
契机
学习爬虫的时候,爬到的数据需要保存的时候,如果插入到MySQL中比较麻烦,先要建表等等之类的,而no-sql数据库MongoDB直接以键值对的形式插入数据库,比较省事省力,不用去考虑字段类型等等,有多少直接插入多少。
安装及可视化工具
mongodb官网上直接下载社区版即可
可视化工具:navicat for MongoDB或是studio 3T
基本语法
目录结构:
- database 数据库
- collection 集合
- document 文档
数据库操作
show databases 查看数据库,如果某一个数据库没有数据,则不显示该数据库
use databaseName[数据库名] 使用数据库,如果该数据库不存在 则创建数据库并切换到该数据库
db 查看当前工作的数据库
db.help() 查看mongodb中的命令
db.dropDatabase() 删除当前使用的数据库 ----区分大小写,小驼峰命名
集合操作
集合:存在于数据库中,集合没有固定的结构,意味着对集合可以插入不同格式和不同类型的数据,一般情况下,插入的数据是有关联性【一致性】
创建
db.createCollection(name,options) # 创建集合
# name的类型为String类型,是创建的集合的名称 options的类型是一个文档,是可选的
show collections 查看当前集合下的文档
options可选字段。
db.createCollection("col",{capped:true,size:100000,autoIndexId:true,max:1000})
根据需求选择即可
如果向一个不存在的集合插入文档,则直接创建该集合
> db.name.insert({"name":"aa"})
WriteResult({ "nInserted" : 1 })
> show collections
invent
myCol
name
删除
db.Collection_NAME.drop()
删除成功返回true,失败false
> db.name.drop()
true
文档操作
文档是一组键值对,在mongodb中不需要设置相同的字段,并且相同的字段不需要相同的数据类型,
和关系型数据库有很大的区别
注意:
- 文档中的键值是有序的
- 文档中的值可以是字符串,也可以是数字,布尔,数组等
- 区分类型的大小写
- 不能出现重复的键
- 键一般都是字符串
插入文档
单条文档插入
db.Collection_NAME.insert(document)
> db.myCol.insert({"name":"zhangsan","age":"20","sex":"male"})
WriteResult({ "nInserted" : 1 })
再插入文档中,如果不指定_id参数,那么MongoDB会为此文档分配一个唯一的Objectld,当前的文档的唯一标识
插入多条文档
db.collection_name.insertMant([{},{},{}])
> db.myCol.insertMany([{"1":"2","3":"4"},{"5":"6","7":"8"}])
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5db130613f1dc6ba7faf7030"),
ObjectId("5db130613f1dc6ba7faf7031")
]
}
> db.myCol.find()
{ "_id" : ObjectId("5db12c5d3f1dc6ba7faf702e"), "name" : "zhangsan", "age" : "20", "sex" : "male" }
{ "_id" : ObjectId("5db12ff83f1dc6ba7faf702f") }
{ "_id" : ObjectId("5db130613f1dc6ba7faf7030"), "1" : "2", "3" : "4" }
{ "_id" : ObjectId("5db130613f1dc6ba7faf7031"), "5" : "6", "7" : "8" }
>
查询文档
语法:
db.COLLECTION_NAME.find(document)
- db.youCollection.find(criteria, filterDisplay)
- criteria :查询条件,可选
- filterDisplay:筛选显示部分数据, 显示指定列数据
- db.集合名.find(): ----查询所有记录。
- db.集合名.find().pretty()------- 查询所有记录,并友好地显示出来(json格式), pretty() 是以格式化方式显示文档信息。
- db.集合名.find({},{name:1, age:1})
- 1:要显示的key【显示】
- 0: 不要显示的key【隐藏】 --------显示所有记录的name和age
- db.集合名.find({name: 'zhangsan'}) -------查看集合中name为zhangsan的文档
- db.集合名.find({name:'zhangsan', age:20}) -------查看集合中name为zhangsan同时age为20的文档
- db.集合名.find({$or: [{age: 22}, {age: 25}]})
- db.集合名.find({"age":{$gt: 20}}) ------查询age > 20的记录
- $lt 小于 <
- $lte 小于等于 <=
- $gt 大于 >
- $gte 大于等于 >=
- $ne 不等于 !=
- db.集合名.find({age : {lt :30, gt : 20}}) --------查找 age 在 (20, 30)之间的纪录
- db.集合名.find({_id:{$in: [1,3,5]}}) -------显示id为1,3和5的文档记录
- db.集合名.find({name: {$regex: "y"}}) ------查询 name的key中包含 y字符的所有文档记录
- db.集合.find().sort({age:1}) -------查找所有,并按age升序排列, 1 升序, -1 降序
> db.myCol.find() 查询所有的文档
{ "_id" : ObjectId("5db12c5d3f1dc6ba7faf702e"), "name" : "zhangsan", "age" : "20", "sex" : "male" }
更新文档
update()
db.COLLECTION_NAME.update(查找条件, 更新数据)
> db.newCol.update({'name':'aaa'},{$set:{"name":"zhangsan"}}) 更新匹配到的第一个文档
> db.newCol.update({'name':'aaa'},{$set:{'name':'jack'}},{multi:true}) 更新所有的文档
update函数执行数据更新操作,该函数接受3个主要参数:criteria,action,options:
- 参数criteria用于指定一个查询,查询选择将要更新的目标记录。
- 参数action用于指定更新信息,也可以使用操作符来完成。
- 参数options用于指定更新文档时的选项,可选值包括:upsert和multi。upsert可以指定如果数据存在就更新,不存在就创建数据;multi选项指定是否应该更新所有匹配的文档,或者只更新第一个文档(默认行为)
save():使用save()
方法中传递的文档数据替换现有文档
db.user.save({'_id':ObjectId("5d6776091738dd1b927a5eab"),'name':'aaa11','age':66,'score':100})
# 覆盖原先文档
删除文档
MongoDB中的 remove()方法用于从集合中删除文档。 remove()方法接受两个参数。 一个是删除条件,第二个是标志:justOne。
criteria - (可选)符合删除条件的集合将被删除。
justOne - (可选)如果设置为true或1,则只删除一个文档
> db.myCol.find()
{ "_id" : ObjectId("5db12c5d3f1dc6ba7faf702e"), "name" : "zhangsan", "age" : "20", "sex" : "male" }
{ "_id" : ObjectId("5db12ff83f1dc6ba7faf702f") }
{ "_id" : ObjectId("5db130613f1dc6ba7faf7030"), "1" : "2", "3" : "4" }
{ "_id" : ObjectId("5db130613f1dc6ba7faf7031"), "5" : "6", "7" : "8" }
> db.myCol.remove({"_id":ObjectId("5db12c5d3f1dc6ba7faf702e")})
WriteResult({ "nRemoved" : 1 })
> db.myCol.find()
{ "_id" : ObjectId("5db12ff83f1dc6ba7faf702f") }
{ "_id" : ObjectId("5db130613f1dc6ba7faf7030"), "1" : "2", "3" : "4" }
{ "_id" : ObjectId("5db130613f1dc6ba7faf7031"), "5" : "6", "7" : "8" }
>db.COLLECTION_NAME.remove(DELLETION_CRITTERIA)
#删除年龄大于等于20的人的信息
db.user.remove({'age':{$gte:20}}) #删除匹配到的全部数据
db.user.remove({'age':{$gte:20}},1) #只删除匹配到的一条语句
db.user.remove() #清空集合
查询
限制筛选的记录
- limit
> db.COLLECTION_NAME.find().limit(NUMBER)
db.user.find().limit(2)
- skip
>db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
db.user.find().limit(1).skip(1) # 显示一条,跳过集合里的第一条
db.user.find().limit(2).skip(1) # 显示两条,跳过集合里的第一条
- sort 排序
>db.COLLECTION_NAME.find().sort({KEY:1})
#mysql:asc desc
#mongodb:1 -1
- 聚合函数
1.aggregate()方法
>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
python和mongodb交互
pip install pymongo
连接方式
from pymongo import MongoClient
# 方式1
client = MongoClient() # 可以连接默认的主机和端口
# 方式2
client = MongoClient(host="localhost", port=27017)
client = MongoClient("localhost", 27017)
# 方式3 URI的方式
client = MongoClient("mongodb://localhost:27017")
连接数据库
# 获取数据库
# mongodb的一个对象可以支持多个数据库,使用MongoClient对象访问相关的属性和方法即可
# 语法:MogonClient的对象,数据库名
db = client.gogo
print(db) # Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'gogo')
# 获取集合 方式1
col1 = db.user
# print(col1)
# Collection(Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'gogo'), 'user')
# 获取集合 方式2
col2 = db["user"]
print(col2) # Collection(Database(MongoClient(host=['localhost:27017'], document_class=dict, tz_aware=False, connect=True), 'gogo'), 'user')
"""
MongoDB中的集合和数据库是懒创建
上述代码在mongodb服务器没有执行任何操作,
当地一个文档插入数据的时候才创建集合和数据库
"""
插入文档
user1 = {
"_id": "101",
"name": "zhangsan",
"age": 10,
}
user2 = {
"_id": "102",
"name": "zhangsan",
"age": 10,
}
user3 = {
"_id": "103",
"name": "zhangsan",
"age": 10,
}
# 1、插入单条数据
# res = col1.insert(user1)
# print(res) # 101 _id
# 2、插入多条数据
res = col1.insert([ user2, user3])
print(res) # ['102', '103']
# python推荐写法
# res = col1.insert_one(user1) 插入单条
# res = col1.insert_many([ user2, user3]) 多条
更新
# 更新
condition = {"name": "zhangsan"}
user = col1.find_one(condition)
print(user)
user["age"] = 20
col1.update(condition, user)
update_one() 单条
# 官方推荐写法 update_one() 单条
condition = {"name": "zhangsan"}
user = col1.find_one(condition)
print(user)
user["age"] = 20
col1.update_one(condition, {"$set": user})
update_many() 多条
condition = {"name": "zhangsan"}
col1.update_many(condition, {"$inc": {"age": 1}})
delete
单条
col1.delete_one({"age": {"$lt": 15}})
多条
col1.delete_many({"age": {"$lt": 15}})
查询
单条
res = col1.find_one({"age": {"$gt": 15}}) # {'_id': '101', 'name': 'zhangsan', 'age': 21} <class 'dict'>
多条
# res = col1.find({"age": {"$gt": 15}}) # <pymongo.cursor.Cursor object at 0x000001DD1A4D5F98> <class 'pymongo.cursor.Cursor'>
print(res.count()) # 统计数目