MongoDB操作指令
基于内存和磁盘之间,不是纯内存的数据库,把内存当做一个中转站,写入和读取都需要中转
1、python与mongodb交互,建立连接
import pymongo
def init_mongodb(arg):
# myclient = pymongo.MongoClient("mongodb://localhost:27017/")
m_client = pymongo.MongoClient(host='127.0.0.1')
my_client = m_client[arg]
return my_client
2、通过id删除mongo中的数据
import pymongo
from bson.objectid import ObjectId
mongo_client = pymongo.MongoClient(host='127.0.0.1')
# 获取所有库名字 ['admin', 'config', 'lianxi', 'local']
dblist = mongo_client.list_database_names()
db_client = mongo_client['xuexiao']
# 获取xuexiao中所有集合的名字 ['all_service', 'file_abstract', 'task']
collection_list = conn.list_collection_names()
mongo_conn = db_client['laoshi']
result = mongo_conn.remove({"_id" : ObjectId("615ffcffa2c5b07358265cd3")})
3、插入数据
# insert insert()方法的参数可以是字典,也可以是列表
my_dict = {'name': 'lisi'}
my_list = [{'name':'yuhong'},{'mobile':'123456'}]
# 插入成功时,result为在mongo中的id,如:6165ab8ad26d61f76f1e1ccb
result = mongo_conn.insert(my_dict)
# 插入成功时,result为在mongo中的id,如:[ObjectId('6165aaa9e972654329e01615'), ObjectId('6165aaa9e972654329e01616')]
result = mongo_conn.insert(my_list)
# 插入成功时, result为InsertOneResult 对象,该对象包含 inserted_id 属性(插入文档的 id 值)
result = mongo_conn.insert_one(my_dict)
mylist = [
{ "name": "Taobao", "alexa": "100", "url": "https://www.taobao.com" },
{ "name": "QQ", "alexa": "101", "url": "https://www.qq.com" },
{ "name": "Facebook", "alexa": "10", "url": "https://www.facebook.com" },
{ "name": "知乎", "alexa": "103", "url": "https://www.zhihu.com" },
{ "name": "Github", "alexa": "109", "url": "https://www.github.com" }
]
# insert_many的参数是嵌套了字典的列表。返回InsertManyResult对象
x = mycol.insert_many(mylist)
# 输出插入的所有文档对应的 _id 值,得到的是一个列表
print(x.inserted_ids)
查询
"""
find_one():可以使用find_one()查询第一条数据。
find(): find() 方法可以查询集合中的数据,类似 SQL 中的 SELECT * 操作,
得到的是一个对象(<pymongo.cursor.Cursor object at 0x7fe9a47c5c50>),需要遍历才能得到每一项。
"""
my_dict = {'name': 'lisi'}
# 可以使用find进行过滤筛选,result得到的是一个对象(Cursor),需要遍历才能得到
result = conn['xuexiao'].find(my_dict)
# 返回三条数据
result1 = conn['xuexiao'].find().limit(3)
# 返回的对象,不含_id字段内容,为1是返回该字段内容,为0不返回该字段内容. (为1可以不写)
for x in conn.find({},{ "_id": 0, "name": 1, "alexa": 1 }):
print(x)
导入与导出数据
备份数据:
mongodump -h 127.0.0.1:27017 --authenticationDatabase admin -u root -p 123456 -d knowledge_database_1 --gzip -o knowledge_database_1
"""
-u 用户名
-p 密码
-d 要备份的库
-o 输出到哪里
--gzip 压缩
"""
恢复数据:
mongorestore --host mongo-server:27017 -u 用户名 -p 密码 --authenticationDatabase="admin" -d 库名 --drop "/data/rule/cwe_knowledge_db/knowledge_database_1" --gzip
导出
mongoexport -h dbhost -d dbname -c colname -o filename --type json/csv -f field
mongoexport -h 127.0.0.1:27017 -d py44 -c stu -o data.json
mongoexport -h 127.0.0.1:27017 -d py44 -c stu -o data.csv --type csv -f name
-h: 服务器地址
-d: 数据库名
-c: 集合名
-o: 导出文件名
--type: 文件类型,默认json格式,可选数据类型json,csv
-f: 需要导出的字段,导出为json格式的数据时可以不指定导出哪些字段,默认全部,导出成csv文件是必须指定
导入
mongoimport -d dbname -c collectionname --file filename --headerline --type json/csv -f field
mongoimport -d AAA -c stu --file data.json
mongoimport -d newstu -c stucsv --file data.csv --headerline --type csv
-d :数据库名
-c :collection名
--type :导入的格式默认json
-f :导入的字段名
--headerline :如果导入的格式是csv,则可以使用第一行的标题作为导入的字段
--file :要导入的文件
修改字段名称
db.集合名称.update({}, {$rename:{"旧键名称":"新键名称"}}, false, true)
参数提示:
第一个false:可选,这个参数的意思是,如果不存在update的记录,true为插入新的记录,默认是false,不插入。
第二个true:可选,mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
#-- 终端指令 --js文件写 写完粘贴 到终端 测试
mongoddb数据 非关系型数据库
大数据
数据采集
存储
mongod -- 内存---磁盘
无需建表建库的, 如果存储了数据, 会自动建表建库
集合 -- 表
文档 -- 行
1. MongoDB的启动服务
1.开启服务 sudo mongod
2.开启客户端 mongo
{
* 服务端启动:sudo mongod
* 需要指令数据保存的位置,创建文件夹 mkdir /data/db
* 终端会阻塞,默认端口27017
* 进入客户端:mongo
* 服务端后台进程(子进程)启动:
* 终端不会阻塞 logpath是日志路径,可以自己新建文件夹和temp.log文件,比如/home/ubuntu/logs/temp.log
* sudo mongod --logpath=/Users/lpf/logs/temp.log --fork
* 关闭数据库服务器,使用kill -9 杀死进程,或进入数据库关闭:
* use admin
* db.shutdownServer()
}
2. mongodb 权限设置
{
服务: sudo mongod
客户端: mongo
2.1 先创建管理员,在admin数据库下操作
use admin
db.createUser({user:'py',pwd:'py',roles:['root']})
2.2 再创建2个普通用户:对py44数据库具有read、readWrite权限;
db.createUser({user:'user1',pwd:'user1', roles:[{role:'read', db:'py44'}]})
db.createUser({user:'user2',pwd:'user2', roles:[{role:'readWrite', db:'py44'}]})
# 创建了 py44 数据库 和 stu的集合,向表中插入数据自动创建表
use py44
db.stu.insert({k:'v'})
db.createCollection("stu")创建stu集合(表)
db.createCollection("sub",{capped:true,size:10}
参数capped:默认值为false表示不设置上线,值为true表示设置上限(容量上限)
参数size:集合所占用的字节数,当capped值为true时,需要指定此参数,表示上线大小,当文档达到上限时,会将之前的数据覆盖,单位为字节。
检查集合是否设定上限:db.集合名.isCapped()
2.3 mongodb 认证方式启动和登录
* 1.服务端:sudo mongod --auth
* 2.进入数据库客户端:mongo
2.4 2.选择admin数据库,认证user1用户,选择py43数据库,在py43数据库下,插入数据,无法成功,因为user1只对py43数据库有read权限;
use admin
db.auth(name,pwd)
db.stu.insert({name:'zhangsan'})
# 2.选择admin数据库,认证user2用户,选择py43数据库,在py43数据库下,插入数据,插入成功,因为user2对py43数据库有readWrite权限,不能使用show dbs,因为user2对其它数据库没有权限;
use admin
db.auth('user2','user2')
db.stu.insert({name:'zhangsan'})
db.stu.find()
# 选择admin数据库,认证user1用户,选择py43数据库,在py43数据库下,插入数据无法成功,但是,可以查询数据
2.5 删除 用户
use admin
db.auth('root用户','pwd')
db.dropUser('用户名')
}
2.MongoDB的数据库操作
{
1.查看默认的数据库 db
2.查看所有的数据库 show dbs或者show databases
3.查看所有的集合(表) db.createCollection('db_table_name')
5.切换数据库 use dbname
6.删除数据库(先进数据库,再执行指令) 1. use xx, 2.db.dropDatabase()
}
3.MongoDB中的集合(表)的操作
{
1.创建集合 db.createCollection()
2.创建内容(文档) db.xx.insert({})
3.删除集合 db.xx.drop()
4.查询所有表 show collections
5.查询所有的内容 db.xx.find()
}
4.文档数据增,删,改
1.增加
1.1 直接增加
db.xx.insert({})
1.2 先字典 在增加
stu_info = {
name:"小明",
age:12,
gender:true,
height:170,
}
data_list = [
{ _id:3,
name:"小明",
age:12,
gender:true,
height:170,
}
]
db.stu.insert(data_list)
{
db.stu.insert({_id:2,user:"小兰",age:16,gender:false})
db.stu.insert({_id:3,user:"小芳",age:18,gender:false})
db.stu.insert({_id:4,user:"大头儿子",age:8,gender:true})
db.stu.insert({_id:5,user:"小头爸爸",age:38,gender:true})
db.stu.insert({_id:7,user:"皮几万",age:25,gender:true})
db.stu.insert({_id : 1, name:'郭靖',hometown:'蒙古',age:20,gender:true})
db.stu.insert({_id : 2, name:'黄蓉',hometown:'桃花岛',age:18,gender:false})
db.stu.insert({_id : 3, name:'华筝',hometown:'蒙古',age:18,gender:false})
db.stu.insert({_id : 4, name:'黄药师',hometown:'桃花岛',age:40,gender:true})
db.stu.insert({_id : 5, name:'段誉',hometown:'大理',age:16,gender:true})
db.stu.insert({_id : 6, name:'段王爷',hometown:'大理',age:45,gender:true})
db.stu.insert({_id : 7, name:'Lily',hometown:'英国',age:45,gender:true})
}
2. 删除数据
1. 默认删除所有符合条件的数据
db.xx.remove({删除条件})
2. 只想删除符合条件的一个数据,justOne对应的值决定删除单条数据还是多条数据,默认是false,可删除多个
db.xx.remove({删除条件},{justOne:true})
例如:db.xx.remove({gender:false}),则小兰小芳被删除
3.删除所有的数据,删除所有要传空字典 把表中数据全删除,表还在,但是把表全删除库就不在了
db.stu.remove({})
3. 修改数据
1. 默认修改或者新增字段; 其他的字段删除了,如果有五个字段,更新后只保留更新的字段,其他字段被删除
db.xx.update(查询条件, 修改内容)
2. 只修改或增加 原有的字段; 其他字段不变 保留 $set
db.xx.update({找},{$set:{}})
3. 只要符合条件 都修改 字段 multi决定是否是批量更新,还是只更新一条数据,并且只有在对数据字段值操作(使用$)的时候才能使用,如果multi不指定则默认是false。
db.xxx.update({},{$set:{}},{multi:true})
db.stu.update({gender:true},{$set:{age:100}},{multi:true})
4. 删除字段 $unset
db.xxx.update({},{$unset:{}})
db.second.update({_id:5},{$unset:{height:1}})
4.保存操作
db.colname.save(data)
save=insert+update
以_id为判断依据,存在该id对应的数据则更新数据,不存在则插入数据
5.数据的基本查询:
1.基本查询{
1.查询所有的数据
db.xx.find()
db.xx.find({})
2.指定条件查询
db.xx.find({查询条件})
3.查询所有内容并有规律的显示
db.xx.find().pretty()
4. 只查找符合条件的一个
db.xx.findOne()
}
2.条件运算 $lt $gt $lte $gte $ne
//年龄大于 20岁的人
db.stu.find({age:{$gt:20}})
3.逻辑运算 $and $or
1. 默认find的多条件 就是 $and
//籍贯是 桃花岛 年龄是18岁的
db.stu.find({'hometown':'桃花岛', age:18})
db.stu.find({
$and: [
{hometown: "桃花岛"},
{age:18}
]
})
2. $or
// 来自大理 或者是女生的
db.stu.find({
$or:[
{hometown:"大理"},
{gender:false}
]
})
3. 混合使用
// 来自桃花岛或者年龄小于45岁 必须是男生
db.stu.find({
$and:[
{
$or:[
{hometown:"桃花岛"},
{age:{$lt:45}}
]
},
{gender: true}
]
})
// 来自大理或者来自蒙古
4.范围运算符 $in $nin
db.stu.find({
hometown:{$in: ['大理', '蒙古'] }
})
5.正则表达式{
db.xx.find(
{字段:'正则表达式'}
)
1. /正则/
db.stu.find(
{name:/黄/}
)
2.{$regex:"正则"} 查找值包含目标的数据
db.stu.find(
{
name:{$regex:"段"}
}
)
3. 忽略大小写
3.1 db.stu.find({name:/lily/i})
3.2 db.stu.find(
{
name:{$regex:"lcf",
$options:"i"}
}
)
}
6.自定义函数 $where
db.stu.find(
{
$where:匿名函数带返回值
}
)
//取年龄 大于20岁的人 age > 20
db.stu.find({
$where: function () {
return this.age > 20
}
})
7、查找某个字段存在的数据
db.cnnvd.find({'search':{$exists:1}}).count()
6.查询结果显示
1.skip 跳过几个显示
2.limit 允许显示几个
//跳过2个 显示4个
注意点: 没有顺序之分
db.stu.find().skip(2).limit(4)
db.stu.find().limit(4).skip(2)
3.投影 显示哪些字段; 显示 true
db.stu.find({gender:true},{name:true})
4.sort 排序: -1降序 1 升序
// 年龄 排降序, 相同的按照id 降序
db.stu.find().sort({age:-1,_id:-1})
5.count 统计个数
//统计所有
db.stu.find().count()
// 根据条件
db.stu.count()
6.distinct 去重
// 取出年龄 小于 60岁的; 籍贯
db.xx.distinct("去重字段",{查询条件})
7.聚合查询:
// 管道有顺序
db.xx.aggregate(
[
{管道1},
{管道2},
]
)
// 多条件的 多件事
$group: 分组
// 数据按照 gender性别分组
db.stu.aggregate(
[
{$group:{_id:'$gender'}}
]
)
// 表达式: $sum $avg $first $last $max $min $push
// 数据按照 性别分组 求年龄的平均值
db.stu.aggregate(
[
{$group:{_id:"$gender", age_avg:{$avg:"$age"}}}
]
)
// 按照籍贯分组, 求年龄和
db.stu.aggregate(
[
{$group:{_id:"$hometown", age_sum:{$sum:"$age"}}}
]
)
// $push 将分组想取出来的数据 放入到一个列表
// 取出 按照性别分组的 所有人的名字
db.stu.aggregate([
{
$group:{
_id:"$gender",
all_name:{$push:"$name"}
}
}
])
$match: 查找符合条件的数据 ; find 区别
// 查询功能一样
// match可以配合管道使用的
// 取出年龄大于20人
db.stu.find({age:{$gt:20}})
db.stu.aggregate([
{
$match:{
age: {$gt: 20}
}
}
])
// 取出年龄小于40的; 按照性别分组求年龄平均值($avg)
db.stu.aggregate([
{$match:{age: {$lt:40}}},
{$group:{_id:"$gender", age_avg:{$avg:"$age"}}}
])
$project:投影取出部分字段; 显示1
// 取出年龄大于20; 按照籍贯分组 求出年龄之和,求年龄平均值; 查看的时候只想看到之和
db.stu.aggregate([
{$match: {age: {$gt:20}}},
{$group: {_id: "$hometown", age_sum:{$sum:"$age"}, age_avg:{$avg:"$age"}}},
{$project: {age_sum:1}}
])
// {$project:{_id:1,age_sum:0}} 错误演示
// db.stu.aggregate(
// {$group:{_id:"$hometown", age_sum:{$sum:"$age"},age_avg:{$avg:"$age"}}},
// {$project:{age_avg:0,age_sum:1}}
// )
$sort: 排序 1升序 -1降序
//先找 45以下 ;再 安籍贯分组 求平均值,求和, 在 降序, 在投影
db.stu.aggregate([
{$match: {age: {$lt:45}}},
{$group: {_id: "$hometown", age_sum:{$sum:"$age"}, age_avg:{$avg:"$age"}}},
{$sort:{_id:1}},
{$project: {age_sum:1}}
])
//注意点: 管道是有顺序的 不能随意颠倒; 根据需求
$skip 跳过几个查看
$limit 允许显示几个
//先跳2个 在显示 4个
db.stu.aggregate(
{$skip:2},
{$limit:4}
)
db.stu.aggregate(
{$limit:4},
{$skip:2}
)
$unwind :将数据列表 分割 拆分
//按照性别分组, 求出人的名字 $push
db.stu.aggregate(
[
{$group: {_id:"$gender", all_name:{$push:'$name'}}},
{$unwind:"$all_name"}
]
)
8.MongoDB的索引操作
1. 创建批量的数据 20W 的数据
for (var index = 0; index < 200000; index++) {
db.stu.insert({
_id:index+1,
name:"name"+(index+1),
age:index+1
})
}
2. 查看 数据的时间 对比 毫秒
db.xx.find().explain('executionStats')
2.1 查看 _id 1毫秒
db.stu.find({_id:166666}).explain('executionStats')
2.2 查看 name 138毫秒--
db.stu.find({name:"name166666"}).explain('executionStats')
2.3 查看 age 119毫秒
db.stu.find({age:166666}).explain('executionStats')
3. 设置 ID索引ensureIndex
db.stu.ensureIndex({name:1})
查询 所有的索引
db.stu.getIndexes()
4. 删除 自定义的索引
db.stu.dropIndex('name_1')
9.MongoDB的备份和恢复
mongodump -h 127.0.0.1:27017 -d stu -o /Users/lpf/Desktop/mongodata
备份: mongodump -h -d -o
-h: host "IP:port"
-d: 备份的数据库名字 db
-o: 备份到哪里去
mongodump -h 127.0.0.1:27017 -d py44 -o ./
mongorestore -h 127.0.0.1:27017 -d newstu --dir /Users/lpf/Desktop/mongodata/py43
恢复: mongorestore -h -d --dir
-h: host
-d: 恢复的数据的名字
--dir :从哪里恢复
mongorestore -h 127.0.0.1:27017 -d pynew44 --dir ./py44
10.python和MongoDB的交互
1.建立链接
2.创建库
3.创建集合
4.插入数据
import pymongo
def init_mongodb(arg):
# myclient = pymongo.MongoClient("mongodb://localhost:27017/")
m_client = pymongo.MongoClient(host='127.0.0.1')
my_client = m_client[arg]
return my_client
// db.createUser({user:'B',pwd:'123456',roles:[{db:'pymo',role:'read'}]})
db.createUser({user:'A',pwd:'123456',roles:['root']})
db.createUser({user:'B',pwd:'123456',roles:[{db:'pystu',role:'read'}]})
插入数据不加主键则mongodb自动添加主键