前言:
此刻同学们对“mongodbpython教程”大致比较关怀,你们都需要分析一些“mongodbpython教程”的相关知识。那么小编在网摘上汇集了一些对于“mongodbpython教程””的相关知识,希望咱们能喜欢,同学们一起来学习一下吧!MongoDB 数据库
"NoSQL"⼀词最早于1998年被⽤于⼀个轻量级的关系数据库的名字随着web2.0的快速发展, NoSQL概念在2009年被提了出来NoSQL在2010年⻛⽣⽔起, 现在国内外众多⼤⼩⽹站, 如facebook、 google、 淘宝、 京东、 百度等, 都在使⽤nosql开发⾼性能的产品对于⼀名程序员来讲, 使⽤nosql已经成为⼀条必备技能NoSQL最常⻅的解释是“non-relational”, “Not Only SQL”也被很多⼈接受, 指的是⾮关系型的数据库
MongoDB的优势易扩展: NoSQL数据库种类繁多, 但是⼀个共同的特点都是去掉关系数据库的关系型特性。 数据之间⽆关系, 这样就⾮常容易扩展
⼤数据量, ⾼性能: NoSQL数据库都具有⾮常⾼的读写性能, 尤其在⼤数据量下, 同样表现优秀。 这得益于它的⽆关系性, 数据库的结构简单
灵活的数据模型: NoSQL⽆需事先为要存储的数据建⽴字段, 随时可以存储⾃定义的数据格式。 ⽽在关系数据库⾥, 增删字段是⼀件⾮常麻烦的事情。 如果是⾮常⼤数据量的表, 增加字段简直就是⼀个噩梦
关于DadaBase的基础命令查看当前数据库: db查看所有的数据库: show dbs / show databases切换数据库: use db_name删除当前数据库: db.DropDatabase()
在mongodb数据库中, 没有新建数据库的指令,可以直接use需要新建的数据库,mongo会自动创建。
// 当前mongo不存在test1 但是照样可以切换use test1//注意点:在数据库没有数据时,数据库并不会真正创建 当插入数据时,就可以使用show dbs查看到test1了
关于集合的基础命令
在mongodb数据库中没有表的概念,数据都是存储在集合中。
集合创建:
// 自动创建集合// 向不存在的集合中第一次加入数据时,集合会被创建出来// 手动创建集合 语法db.createCollection(set_name, options)db.createCollection("stu")db.createCollection("sub", {capped: true, size: 10})// 参数capped: 默认值为false表示不设置上限,值为true表示设置上限// 参数size: 当capped值为true时,需要指定此参数,表示上限大小。// 当文档达到上限时,会将之前的数据覆盖,单位为字节。// 查看集合show collections// 删除集合db.集合名称.drop()
数据类型Object ID:文档IDString:字符串 该属性是最常用的数据类型,并且为一个有效的UTF-8字符集Boolean:存储一个布尔值,true或者falseInteger:整数 可以是32位或64位,取决于服务器Double:浮点值Arrays:数组或列表,多个值存储到一个键Object:用于嵌入式的文档,即一个值为一个文档Null:Null值Timestamp: 时间戳 表示1970-1-1到现在的总秒数Date:存储当前日期或时间的UNIX时间格式
每个文档都有自己的属性,为_id。保证每个文档的唯一性
可以自己去设置_id插入文档,如果没有提供,那么mongodb为每个文档提供一个独特的_id,类型为object ID
object ID是一个12字节的十六进制数:
前4个字节为当前时间戳接下来3个字节为机器ID后2个字节为MongoDB的服务进程ID最后3个字节是简单的增量值
数据操作数据插入
//db.集合名称.insert(docment)// 例如db.stu_test.insert({"name": "xiaoming", "age": 10})// 查询当前集合数据 并返回_iddb.stu_test.find()// 在终端中插入的数据为json 并且数据中的键可以省略双引号db.stu_test.insert({name: "xiaohong", age: 18})db.stu_test.find()
数据保存
// db.集合名称.save(document)// 如果文档的_id已经存在则修改,如果文档的_id不存在则添加数据db.stu_test.insert({_id: 10010, name: "xiaoming", age: 30})// 尝试插入数据 如果当前_id相同,则报错[当前id值重复]db.stu_test.insert({_id: 10010, name: "xiaoming", age: 40})// 调用save保存则更新数据db.stu_test.save({_id: 10010, name: "xiaoming", age: 40})
数据更新
// db.集合名称.update(<query>, <update>, {multi: <boolean>})// query: 查询条件// update: 更新操作符// multi: 可选参数,默认为false。// 表示只更新找到的第一条记录,值为true则更新满足条件的全部数据// 当前这条语句会替换之前的记录,则原数据中的age会消失db.stu_test.update({name: "xiaowang"}, {name: "xiaozhao"})// 为了不影响除了name之外的其他数据 需要使用$set语法db.stu_test.update({name: "xiaowang"}, {$set: {name: "xiaozhao"}})// 更新所有符合条件的数据 multi参数必须和$符配合使用db.stu_test.update({name: "xiaowang"}, {$set: {name: "xiaozhao"}}, {multi: true})
数据删除
// db.集合名称.remove(<query>, {justOne: <boolean>})// query: 删除指定文档的条件// justOne: 可选参数,如果设置为true或1,删除一条。默认false,表示删除多条// 删除符合条件的全部数据db.stu_test.remove({name: "xiaozhao"})// 删除一条db.stu_test.remove({name: "xiaozhao"}, {justOne: true})
学习数据查询之前的数据准备
db.getCollection("products").insert([ { _id: 100, sku: "abc123", description: "Single line description"} ]);db.getCollection("products").insert([ { _id: 101, sku: "abc789", description: "First line\nSecond line"} ]);db.getCollection("products").insert([ { _id: 102, sku: "xyz456", description: "Many spaces before line"} ]);db.getCollection("products").insert([ { _id: 103, sku: "xyz789", description: "Multiple\nline description"} ]);db.getCollection("products").insert([ { _id: 104, sku: "abc123", description: "Single line description"} ]);db.getCollection("stu_info").insert([ { _id: ObjectId("626ba04fce0a56f10342b6f3"), name: "郭靖", hometown: "蒙古", age: 20, gender: true} ]);db.getCollection("stu_info").insert([ { _id: ObjectId("626ba07cce0a56f10342b6f4"), name: "黄蓉", hometown: "桃花岛", age: 18, gender: false} ]);db.getCollection("stu_info").insert([ { _id: ObjectId("626ba0acce0a56f10342b6f5"), name: "华筝", hometown: "蒙古", age: 18, gender: false} ]);db.getCollection("stu_info").insert([ { _id: ObjectId("626ba0d2ce0a56f10342b6f6"), name: "黄药师", hometown: "桃花岛", age: 40, gender: true} ]);db.getCollection("stu_info").insert([ { _id: ObjectId("626ba0f1ce0a56f10342b6f7"), name: "段誉", hometown: "大理", age: 16, gender: true} ]);db.getCollection("stu_info").insert([ { _id: ObjectId("626ba10bce0a56f10342b6f8"), name: "段王爷", hometown: "大理", age: 45, gender: true} ]);db.getCollection("stu_info").insert([ { _id: ObjectId("626ba12cce0a56f10342b6f9"), name: "洪七公", hometown: "华山", age: 18, gender: true} ]);
数据查询find方法
// 普通查询: find()db.集合名称.find({条件文档})// 进入到stu_info集合中进行查询 数据源使用js文件进行录入db.stu_info.find({age:20})// 查询一个: findOne()// db.集合名称.findOne({条件文档})db.stu_info.findOne({age:18})// pretty(): 将结果格式化// db.集合名称.find({条件文档}).pretty()db.stu_info.find().pretty()
比较运算符等于:默认是等于判断,没有运算符小于:$lt小于等于:$lte大于:$gt大于等于:$gte不等于:$ne
db.stu_info.find({age: {$gte: 18}})
范围运算符
// 使用"$in"进行返回查询 符合18或28的返回db.stu_info.find({age: {$in: [18, 28]}})
逻辑运算符
// 并且查询db.stu_info.find({age: 18, hometown: "桃花岛"})// 或者查询// db.集合名称.find({$or: [{查询条件}, {查询条件}]})db.stu_info.find({$or: [{age: 18}, {hometown: "桃花岛"}]})// 将之前所学的查询进行整合使用// 如果语句过长,可以使用编辑器写上查询语句 并且换行不影响db.stu_info.find({$or: [{age: {$gte: 45}}, {hometown: {$in:["桃花岛", "华山"]}}]})
正则表达式查询
// 使用//或$regex编写正则表达式db.products.find({sku:/^abc/})db.products.find({sku: {$regex: "789$"}})
limit与skip
// ⽅法limit(): ⽤于读取指定数量的⽂档// db.集合名称.find().limit(NUMBER)// 查询两条信息db.products.find().limit(2)// 查询除了前两条之外的所有记录db.products.find().skip(2)// 组合使用db.products.find().skip(2).limit(2)
自定义查询
// 使⽤$where后⾯写⼀个函数, 返回满⾜条件的数据// 查询年龄⼤于30的学⽣db.stu_1.find({$where: function(){return this.age<=18}})
投影
// 在查询到的返回结果中,只选择必要的字段// 如果不想显示_id,需要单独设置_id: 0// db.集合名称.find({条件}, {字段名称1, 字段名称2...})db.stu_info.find({age: {$gt: 18}}, {name: 1, _id: 0})// 无条件进行投影查询db.stu_info.find({}, {name: 1, _id: 0})
排序
// 方法sort() 用于对集合进行排序// db.集合名称.find().sort({字段: 1})// 1为升序 -1为降序db.stu_info.find().sort({age: -1})// 多条件排序db.stu_info.find().sort({age: -1, gender: -1})// 筛选年龄大于18并使用age进行正序排序db.stu_info.find({age: {$gt: 18}}).sort({age: 1})
记录统计
// 统计学生个数db.stu_info.find().count()// 统计年龄大于18的学生个数db.stu_info.find({age: {$gt: 18}}).count()// 第二种写法db.stu_info.count()db.stu_info.count({age: {$gt: 18}})
数据去重
// 对地址进行去重db.stu_info.distinct("hometown")// 结合条件查询去重db.stu_info.distinct("hometown", {age: {$gt: 20}})
聚合操作
聚合(aggregate)是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果。
db.集合名称.aggregate({管道:{表达式}})
常用管道
$group: 将集合中的⽂档分组, 可⽤于统计结果 $match: 过滤数据, 只输出符合条件的⽂档 $project: 修改输⼊⽂档的结构, 如重命名、增加、删除字段、创建计算结果 $sort: 将输⼊⽂档排序后输出 $limit: 限制聚合管道返回的⽂档数 $skip: 跳过指定数量的⽂档, 并返回余下的⽂档 $unwind: 将数组类型的字段进⾏拆分
表达式
$sum: 计算总和, $sum:1 表示以⼀倍计数 $avg: 计算平均值 $min: 获取最⼩值 $max: 获取最⼤值 $push: 在结果⽂档中插⼊值到⼀个数组中 $first: 根据资源⽂档的排序获取第⼀个⽂档数据 $last: 根据资源⽂档的排序获取最后⼀个⽂档数据
$group将集合中的文档分组,可用于统计结果_id表示分组的依据,使用某个字段的格式为"$字段"
案例:统计男生、女生的总人数
// $sum: 1 可以理解成统计文档中分组之后的每一条数据的结果 * 1db.stu_info.aggregate( { $group: {_id: "$gender", counter: {$sum: 1}} })
案例:按照 gender 进行分组,获取不同组数据的个数和平均年龄
db.stu_info.aggregate( { $group: {_id: "$gender", count: {$sum: 1}, avg_age: {$avg: "$age"}} })
group by null将集合中所有的文档分为一组案例:求学生总人数、平均年龄
db.stu_info.aggregate( { $group: {_id: null, counter: {$sum: 1}, avg_age: {$avg: "$age"}} })
group的注意点$group 对应的字典中有几个键,结果中就有几个键分组依据需要放在_id后面取不同的字段需要在字段前加$,例如:$gender、$age
$project修改文档的结构。如:重命名、增加字段、删除字段、创建计算结果
案例:查询学生的姓名、年龄
// 类似于投影db.stu_info.aggregate( { $project: {_id: 0, name: 1, age: 1} })
案例:查询性别数据、人数统计、平均年龄,并以中文显示
db.stu_info.aggregate( { $group: {_id: "$gender", count: {$sum: 1}, avg_age: {$avg: "$age"}} }, { $project: {"性别": "$_id", "人数统计": "$count", "平均年龄": "$avg_age", _id: 0} })
$match用于过滤数据,只输出符合条件的文档match是管道命令,能将结果交给下一个管道,find()无法实现
案例: 查询年龄大于20的男生
db.stu_info.aggregate( { $match: {age: {$gt: 20}} })
案例: 查询年龄大于20的男生人数、女生人数,并以中文字段输出
db.stu_info.aggregate( { $match: {age: {$gt: 20}}, }, { $group: {_id: "$gender", counter: {$sum: 1}} }, { $project: {"性别": "$_id", "统计人数": "$counter", _id: 0} })# 拓展:查询年龄大于20或者归属地在蒙古或大理的人数db.stu_info.aggregate( { $match: { $or: [ { age: {$gt: 20} }, { hometown: {$in: ["蒙古", "大理"]} } ] }, }, { $group: {_id: "$gender", counter: {$sum: 1}} }, { $project: {"性别": "$_id", "统计人数": "$counter", _id: 0} })
$sort将输入文档排序后输出
案例:查询学生信息,按年龄升序
db.stu_info.aggregate( { $sort: {age: 1} })
案例:查询男生人数、女生人数。按人数降序
db.stu_info.aggregate( { $group: {_id: "$gender", counter: {$sum: 1}} }, { $sort: {counter: -1} })
$limit 与 $skip$limit限制聚合函数返回的文档数
案例:查询两条学生信息
db.stu_info.aggregate( {$limit: 2})
$skip跳过指定数量的文档,并返回余下的文档
案例:查询从第三条数据开始的学生信息
db.stu_info.aggregate( {$skip: 2})
案例:取出当前从第一位学生之后的一条学生信息
db.stu_info.aggregate({$skip: 1}, {$limit: 1})
索引 - 查询优化创建测试数据
for(i = 0; i < 100000; i++){ db.test_data.insert({name: "test" + i, age: i})}// 查询数据db.test_data.find({name: "test10000"})// 获取查询数据所花费的时间db.test_data.find({name: "test10000"}).explain("executionStats")
建立索引
// 语法示例// 1代表升序 -1代表降序// db.集合名称.ensureIndex({属性: 1})db.test_data.ensureIndex({name: 1})db.test_data.find({name: "test10000"}).explain("executionStats")// 查看索引db.test_data.getIndexes()
索引使用
在默认情况下创建的索引不是唯一索引
创建唯一索引
// 参数1代表方向 可以设置为1或者-1db.test_data.ensureIndex({"name": 1}, {"unique": true})创建唯一索引并消除重复
// mongo3之后的版本 dropDups 失效db.test_data.ensureIndex({"name": 1}, {"unique": true, "dropDups": true})建立联合索引
db.test_data.ensureIndex({name: 1, age: 1})
Python对接MongoDB安装pymongo
pip install pymongo -i
代码演示
# 导入模块from pymongo import MongoClient# 实例化client建立连接并指定集合 当前mongo演示为本地client = MongoClient(host='127.0.0.1', port=27017)collection = client['mongo_data_info']['test_python']# 插入一条数据res = collection.insert_one({"name": "xiaoming", "age": 10})print(res)# 插入多条数据data_list = [{"name": "test{}".format(i)} for i in range(10)]collection.insert_many(data_list)# 查询一条数据t_1 = colltction.find_one({"name": "xiaowang"})print(t_1)# 查询所有记录t_2 = collection.find({"name": "xiaowang"})# 当前返回的是一个游标对象print(t_2)for i in t_2: print(i) # 对游标对象进行列表类型转换print(list(t_2))# 更新一条数据collection.update_one({"name": "test1"}, {"$set": {"name": "new_test1"}})# 更新全部数据collection.update_many({"name": "test1"}, {"$set": {"name": "new_test1"}})# 删除一条数据collection.delete_one({"name": "test10"})# 删除全部数据collection.delete_many({"name": "test9"})
标签: #mongodbpython教程