MongoDB 上手开发实践(入门上手开发这一篇就够了)
前言
MongoDB是一个介于 关系数据库 和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似 json 的 bson 格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立 索引 。
也有一些其他的nosql的典型数据库,比如redis,hbase等,然而他们之间还是有区分的。(市面上有很多不错的数据库,这里就不一一列举了)
|
name |
type |
|
mongodb |
面向文档 |
|
redis |
键值存储 |
|
hbase |
列存储 |
- 数据类型
- MongoDB CRUD Operrations基础增删改查
- Aggregation 聚合操作
- 查询调优
- 索引
123这三个点基本熟悉就代表能够满足平时的开发需求了,然后辅助一下数据结构设计的提升能更好的完成产品的开发;在123的基础上叠加45基本就能覆盖线上数据的搜索调优了。
"实体结构"
person:{
name:"string",
age:"int",
children:"array person",
parentId:"string"
}
创建表(collection)
//命令行
use test
db.createCollection("person")
插入数据
//插入一个爸爸
db.person.insertOne({
name:"Baba",
age:Int32(),
children:[],
parentId:null
})
//插入了几个儿子
db.person.insertOne({
name:"Child1",
age:Int32(),
children:[],
parentId:null
}) db.person.insertMany(
[{
name:"Child2",
age:Int32(),
children:[],
parentId:null
},{
name:"Child3",
age:Int32(),
children:[],
parentId:null
}
])
创建数据OK了,但是作为一个有梦想的程序员,必须要再了解一下script,嘿嘿
//循环大法
for(var i=0;i<10;i++){
db.person.insertOne({
name:"robot"+i,
age:Int32(Math.floor(Math.random() * 100)),
children:[],
parentId:null
})
}
截止到上一步我们已经在数据库test中的person表插入了几条数据了,这里做几个简单的查询熟悉下数据查询
//查询全部
db.person.find({})
//查询Baba
db.person.find({name:"Baba"},{age:1}).sort({age:1})
//查询不包含baba
db.person.find({name:{$ne:"Baba"}})
//查询年龄在(200,1000)的数据,$lte $gte中包含等于,时间的大于小于也是如此
db.person.find({age:{$lt:1000,$gt:200}},{age:1,_id:0})
//查询name中包含robot的数据,"i"代表忽略大小写,//就是正则
db.person.find({name:/robot/i}).skip(0*5).limit(5)
//或逻辑查询,$and为与逻辑,格式相同,而$and一般用于内嵌对象的与
db.person.find({$or:[{name:"Baba"},{name:/chi/i}]})
简单查询后,尝试一下update
//将名字叫Child1的parentId修改为Baba的_id
//将baba的children的arr中填充Child1的_id并且年龄+1
//注意push和addtoset的区别
var baba = db.person.findOne({name:"Baba"});
db.person.updateOne({name:"Child1"},{$set:{parentId:baba._id}})
var child1 = db.person.findOne({name:"Child1"});
db.person.updateOne({_id:baba._id},{$addToSet:{children:child1._id},$inc:{age:1}})
//重复多次运行会发现CHILDREN会出现重复数据
db.person.updateOne({_id:baba._id},{$push:{CHILDREN:child1._id}})
//查询children中不包含指定id的数据
db.person.find({children:{$in:[child1._id]}}) //----------------------------华丽分割线---------------------------------------// //通过上面的语句会对set inc push addtoset有一定的了解,那就把CHILDREN中的移除吧,
var baba = db.person.findOne({name:"Baba"});
var child1 = db.person.findOne({name:"Child1"});
db.person.updateOne({_id:baba._id},{$push:{"CHILDREN":new ObjectId()}})
db.person.updateOne({_id:baba._id},{$pull: {"CHILDREN":child1._id}})
db.person.updateOne({_id:baba._id},{$set:{"CHILDREN":[]}})
//查看存在CHILDREN字段的数据
db.person.find({CHILDREN:{$exists: true}})
//彻底删除字段
db.person.updateMany({},{$unset:{"CHILDREN":""}})
基本的CRUD我们已经知道了,接下来是MongoDB作为非关系型数据库厉害的地方了,聚合(aggregate)
db.person.updateMany({name:/robot/i},{$set:{obj:[
{key:"db",value:"mongo"},
{key:"db",value:"redis"},
{key:"db",value:"hbase"}
]}})
db.person.aggregate()
.match({name:/robot/i}) //query
.project({nm:"$name",_id:1,age:1,obj:1}) //精简属性
.unwind("$obj") //一般用来切分内嵌array,做数据聚合时经常会用到
.group({ _id: "$nm", count: { $sum: 1 } }) //按照某个键分组聚合
.sort({"count":-1})
.limit(5)
//这句比较特殊,处理内嵌数组对象的值,$elemMatch是筛选内嵌array对象的关键字,该查询匹配到的数据将会在Mongo内存中把内嵌array匹配到的对象置顶与array的第一个,而接下来的"obj.$.value"是将改内嵌array对象中的第一个的value修改成"mongodb"
db.person.updateMany({obj:{$elemMatch: {value:"mongo"}}},{$set:{"obj.$.value":"mongodb"}})
//类关系型数据库join
db.person.aggregate(
[{
$lookup: {
from: "person",
localField: "_id",
foreignField: "parentId",
as: "sons"
}
}])
mongodb version 4.0之后的版本新增了transaction(事务)的功能,真的可以向mysql,mssql那样回滚了,不是像redis事务那样的,大家可以去了解下。
查询调优
//这里match是让你填筛选条件,请别搞错
db.collection.find({"match"}).explain("executionStats") //查询结果关键字含义
executionStats.executionSuccess:是否执行成功
executionStats.nReturned:满足查询条件的文档个数,即查询的返回条数
executionStats.executionTimeMillis:整体执行时间
executionStats.totalKeysExamined:索引整体扫描的文档个数,和早起版本的nscanned 是一样的
executionStats.totalDocsExamined:document扫描个数, 和早期版本中的nscannedObjects 是一样的
executionStats.executionStages:整个winningPlan执行树的详细信息,一个executionStages包含一个或者多个inputStages
executionStats.executionStages.stage:这里是FETCH去扫描对于documents,后面会专门用来解释大部分查询使用到的各种stage的意思
executionStats.executionStages.nReturned:由于是FETCH,所以这里该值与executionStats.nReturned一致
executionStats.executionStages.docsExamined:与executionStats.totalDocsExamined一致executionStats.inputStage中的与上述理解方式相同
explain.executionStats.executionStages.works:被查询执行阶段所操作的“工作单元(work units)”数。
explain.executionStats.executionStages.advanced:优先返回给父stage的中间结果集中文档个数
explain.executionStats.executionStages.isEOF:查询执行是否已经到了数据流的末尾 //stage类型的含义
COLLSCAN :全表扫描
IXSCAN:索引扫描
FETCH::根据索引去检索指定document
SHARD_MERGE:各个分片返回数据进行merge
SORT:表明在内存中进行了排序(与前期版本的scanAndOrder:true一致)
SORT_MERGE:表明在内存中进行了排序后再合并
LIMIT:使用limit限制返回数
SKIP:使用skip进行跳过
IDHACK:针对_id进行查询
SHARDING_FILTER:通过mongos对分片数据进行查询
COUNT:利用db.coll.count()之类进行count运算
COUNTSCAN:count不使用用Index进行count时的stage返回
COUNT_SCAN:count使用了Index进行count时的stage返回
SUBPLA:未使用到索引的$or查询的stage返回
TEXT:使用全文索引进行查询时候的stage返回
索引
索引方面直接点上方的链接吧,官方这个讲的还是比较好理解的,这里就不展开说了。相信各位小伙伴一看便知
最后,响应一下咱们大大的口号 撸起袖子加油干,尝试一下心里就优普啦。谢谢大家

如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!
本文版权归作者和博客园共有,来源网址:https://www.cnblogs.com/DanielYao/欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
MongoDB 上手开发实践(入门上手开发这一篇就够了)的更多相关文章
- MongoDB 极简实践入门
原作者StevenSLXie; 原链接(https://github.com/StevenSLXie/Tutorials-for-Web-Developers/blob/master/MongoDB% ...
- 转:入门Webpack,看这篇就够了
写在前面的话 阅读本文之前,先看下面这个webpack的配置文件,如果每一项你都懂,那本文能带给你的收获也许就比较有限,你可以快速浏览或直接跳过:如果你和十天前的我一样,对很多选项存在着疑惑,那花一段 ...
- 入门Webpack,看这篇就够了
来源于:http://www.jianshu.com/p/42e11515c10f 写在前面的话 阅读本文之前,先看下面这个webpack的配置文件,如果每一项你都懂,那本文能带给你的收获也许就比较有 ...
- 转载:入门Webpack,看这篇就够了
写在前面的话 阅读本文之前,先看下面这个webpack的配置文件,如果每一项你都懂,那本文能带给你的收获也许就比较有限,你可以快速浏览或直接跳过:如果你和十天前的我一样,对很多选项存在着疑惑,那花一段 ...
- 入门 Webpack,看这篇就够了
转:https://segmentfault.com/a/1190000006178770 2018年8月25日更新,目前 webpack 已经更新值 4.17.1 ,本文所用到的各种库或多或少有些过 ...
- 入门 Webpack,看这篇就够
写在前面的话 阅读本文之前,先看下面这个webpack的配置文件,如果每一项你都懂,那本文能带给你的收获也许就比较有限,你可以快速浏览或直接跳过:如果你和十天前的我一样,对很多选项存在着疑惑,那花一段 ...
- SpringBoot入门学习看这一篇就够了
1.SpringBoot是什么? SpringBoot是一套基于Spring框架的微服务框架. 2.为什么需要SpringBoot 由于Spring是一个轻量级的企业开发框架,主要的功能就是用于整合和 ...
- angular2入门,就这一篇就够了
背景与概念: AngularJS2 是一款开源JavaScript库,由Google维护,用来协助单一页面应用程序运行. AngularJS2 是 Angular 1.x 的升级版本,性能上得到显著的 ...
- Java并发编程入门,看这一篇就够了
Java并发编程一直是Java程序员必须懂但又是很难懂的技术内容.这里不仅仅是指使用简单的多线程编程,或者使用juc的某个类.当然这些都是并发编程的基本知识,除了使用这些工具以外,Java并发编程中涉 ...
- Elasticsearch入门,看这一篇就够了
目录 前言 可视化工具 kibana kibana 的安装 kibana 配置 kibana 的启动 Elasticsearch 入门操作 操作 index 创建 index 索引别名有什么用 删除索 ...
随机推荐
- Project Euler Problem 21-Amicable numbers
先说最暴力的算法,直接对一万内的每个数字暴力分解因子(对每个数字的时间复杂度是O(sqrt(n)的),然后,用个数组记录下来因子和,然后寻找 亲密数. 好一点:要先打个素数表,然后对每个数字,分解素因 ...
- C++第三次作业:友元类
友元类 将数据与处理数据的函数封装在一起,构成类,即实现了数据的共享又实现了隐藏,无疑是面向程序设计的一大优点,但是封装并不总是完美的,一旦需要涉及到一个类的两个对象的数据处理问题该怎么办?无论是设计 ...
- ubuntu18.04 挂载ntfs硬盘无法写入解决办法
win10和ubuntu18.04双系统,在ubuntu下通过/etc/fstab挂载ntfs硬盘无写入权限,尝试通过chmod修改写入权限和ntfs-config图形工具修改写入权限均失败.在ubu ...
- Jquery FormData文件异步上传 快速指南
网站中文件的异步上传是个比较麻烦的问题,不过现在通过jquery 可以很容易的解决这个问题: 使用jquery2.1版本,较老版本不支持异步文件上传功能: 表单代码: <form id=&quo ...
- jq实现简单手风琴效果
文章地址:https://www.cnblogs.com/sandraryan/ 利用slideUp slideDown动画 <!DOCTYPE html> <html lang=& ...
- 2019-9-2-win10-uwp-车表盘-径向规
title author date CreateTime categories win10 uwp 车表盘 径向规 lindexi 2019-09-02 12:57:38 +0800 2018-2-1 ...
- H3C 配置CHAP验证
- Python--day21--异常处理
初识try: except -->异常处理 万能异常的用法:except Exception as error:
- The 10th Shandong Provincial Collegiate Programming Contest H.Tokens on the Segments(贪心+优先级队列 or 贪心+暴力)
传送门 •题意 二维平面上有 n 条线段,每条线段坐标为 $(l_i,i),(r_i,i)$: 平面上的每个整点坐标上都可以放置一枚硬币,但是要求任意两枚硬币的横坐标不相同: 问最多有多少条线段可以放 ...
- P1014 高精度减法
题目描述 给你两个很大的正整数A和B,你需要计算他们的差. 输入格式 输入一行包含两个正整数A和B,以一个空格分隔(A和B的位数都不超过 \(10^5\) ,但是B有可能比A大) 输出格式 输出一行包 ...