初入MongoDB

业务需求,需要用到MongoDB。向来一直是mysql数据库的思想,一下转换为nosql还是很不适应。经过一个月的开发,写一下自己的感触。本文会对应mysql数据库进行说明。

数据库类型

文档型数据库:存储的数据是非结构化数据。文档存储一般用类似 json 的格式存储,存储的内容是文档型的。

相比mysql来说,mysql的表是高度结构化的,若添加字段可能需要修改表结构。MongoDB的话没有这个烦恼,在其中的每条数据可以认为一个“文档”。比如,一篇文章+评论,它可以存储为一个json,囊括了所有的信息,直接存入数据库。并且可以动态的横向扩展,不用担心字段不存在的问题。

结构对比

关系型数据库术语/概念 MongoDB 术语/概念 解释/说明
Database Database 数据库
Table Collection 数据库表/集合
Row Document 数据记录行/文档
Column Field 数据列/数据字段
Index Index 索引
Table joins 表关联/MongoDB 不支持(可以使用聚合查询)
Primary Key Object ID 主键/MongoDB 自动将_id 设置为 主键

接下来介绍一下项目中遇到的查询,以nodejs为例

使用 & 高级查询

基本查询

//分页排序参数
let opt = {
sort: {username: 1},
skip: (value.pageNum - 1) * value.pageSize,
limit: value.pageSize,
}
//条件
let query = {status: {$ne: -1}}
if (params.keyWords) {
//正则表达式
let reg = new RegExp(value.keyWords)
query['$or'] = [
{nickname: reg},
{phone: reg},
]
}
let admins = await AdminModel.getByQuery(query, '', opt)
let admin = await AdminModel.getOneByQuery(query)

查询方法

//查询多条
getByQuery(query, fileds, opt) {
return this.model.find(query, fileds, opt).exec();
}
//查询单条
getOneByQuery(query, fileds, opt) {
return this.model.findOne(query, fileds, opt).exec();
}
//数量查询
countByQuery(query) {
return this.model.countDocuments(query)
}
//更新
update(conditions, update, options) {
return this.model.updateMany(conditions, update, options);
}
//去重查询
distinct(query, field) {
return this.model.find(query).distinct(field);
}
//保存
save(model) {
model = model instanceof this.model ? model : new this.model(model);
return model.save();
}
//更新
update(conditions, update, options) {
return this.model.updateMany(conditions, update, options);
}

关联查询

有时候由于业务的需要,需要关联查询。例如,查询某部门的信息,需要带有相应的负责人。

这里呢,需要在dept(部门表)中添加相应用户表(user)表的objectId,就是MongoDB生成的_id

const Schema = Model.SchemaExt({
// userId为字段名称,ref中的“user” 代办表名
userId: {type: ObjectId, ref: "user"}, // 负责人
code: {type: String, required: true, unique: true}, // 部门编号
name: {type: String, required: true}, // 部门名称
//...
})

这样的话,我们可以使用聚合查询查询出相关数据

//这里的populate,代表的是字段名称
getByIdPopulate(id, populate) {
return this.model.findOne({_id: id}).populate(populate).exec();
}

查询结果

{
code: 001
name: 山东分部
userId: {
_id: xxxxx,
username: xx,
phone: xxx
}
}

聚合查询

这样引申出另外一个问题,如果我需要根据手机号查找部门呢

let listedModel = await deptModel.aggregate([
//关联表,form需要关联的表,localField自己的字段,foreignField关联到表的字段,as关联出的内容key
{
$lookup: {
from: "admins",
localField: "admin",
foreignField: "_id",
as: "adminDetail"
}
}, {
$unwind: '$adminDetail'
}, {
//查询条件,这里query = {'adminDetail.phone': xxx}
$match: query,
}, {
//分页
$facet: {
data: [{
$sort: opt.sort
}, {
$skip: opt.skip
}, {
$limit: opt.limit
}],
count: [{
$group: {
_id: "count",
total: {$sum: 1}
},
}]
}
}
])

初入MongoDB的更多相关文章

  1. 初入SG-UAP

    初入SG-UAP SpriderMan 关注 2019.06.19 14:10 字数 1130 阅读 10评论 0喜欢 0 初次接触SG-UAP,将自己的见解以文字形式记录下来,希望能对初入的伙伴们有 ...

  2. Scala初入

    何为Scala物 Scala为基于JVM虚拟机中的面向对象与函数式编程思想并且完全兼容Java的混合编程语言,可以是Scala与Java是同根同源的,既然Scala与JAVA都是基于JVM之上的编程语 ...

  3. 初学HTML5、初入前端

    学习HTML5是一个漫长的过程,当中会遇到很多技术与心态上的变化.刚开始学习,我们不能发力过猛,需要一个相对稳定的状态去面对.多关注一些自己感兴趣的网站和技术知识,建立自己的信心与好奇心,为以后的学习 ...

  4. 0x00linux32位汇编初入--前期准备

    0x00汇编初入--前期准备 一.汇编工具 在linux平台下常用的编译器为as,连接器为ld,使用的文本编辑器为vim,汇编语法为att 以下是一些工具: addr2line 把地址转换为文件名和行 ...

  5. 初入职场的建议--摘自GameRes

    又开始一年一度的校招了,最近跑了几个学校演讲,发现很多话用短短的一堂职业规划课讲还远远不够,因为那堂课仅仅可能帮大家多思考怎样找到一份合适的工作,并没有提醒大家怎样在工作中发展自己的职业. 见过这么多 ...

  6. 【Xbox one S】开箱&开机&初入坑心得

    再来一发水贴,先上产品标准照镇贴: 前言 身为一个资深单机游戏玩家,常年混迹在PC平台,但内心深处一直对主机有种迷之向往,感觉那才是单机游戏的正处之地,坐沙发上拿着手柄对着电视跌宕起伏才是正确的游戏姿 ...

  7. Git初入

    Git记录 使用git 也有一段时间了, git的入门级了解也就不再多说, 但平常使用中, 仍然会遇到很多问题, 在此记录一二. 在查资料的过程中, 发现了两个比较好的资料: 特别是第二个, 相当详细 ...

  8. SuperMap iClient for JavaScript初入

    SuperMap iClient for JavaScript初入 介绍SuperMap for Js的简单使用. 推荐先看下这篇文档:SuperMap iClient for JavaScript ...

  9. 初入前端框架bootstrap--Web前端

    Bootstraps是一种简洁.直观.强悍的前端开发框架,它让web开发更迅速.简单.对于初入Bootstrap的小白,高效进入主题很重要,能为我们节省很多时间,下面我将对使用Bootstrap开发前 ...

随机推荐

  1. golang——net/rpc包学习

    1.rpc包 rpc包提供了通过网络或其他I/O连接对一个对象的导出方法的访问. 只有满足如下标准的方法才能用于远程访问,其余方法会被忽略: (1)方法是导出的(2)方法有两个参数,都是导出类型或内建 ...

  2. kubernetes生产实践之mysql

    简介 kubedb mysql 生命周期及特性 Supported MySQL Features Features Availability Clustering ✓ Persistent Volum ...

  3. P2516 [HAOI2010]最长公共子序列 题解(LCS)

    题目链接 最长公共子序列 解题思路 第一思路: 1.用\(length[i][j]\)表示\(a\)串的前\(i\)个字符与\(b\)串的前\(j\)个字符重叠的最长子串长度 2.用\(num[i][ ...

  4. python登陆界面尝试

    示例1: """ 编写一个程序 用户可以输入用户名和密码 用户有三次机会 登录成功可以进行相应的操作 输入Q退出系统 """ name_li ...

  5. java例题_10小球 自由落体

    1 /*10 [程序 10 自由落体] 2 题目:一球从 100 米高度自由落下,每次落地后反跳回原高度的一半: 3 求它在 第 10 次落地时,共经过多少米? 4 第 10 次反弹多高? 5 */ ...

  6. Linux命令的应用

    目录 Linux命令 Linux文件管理命令 用户管理 权限管理 vi文本编辑器 find查找命令 磁盘管理命令 压缩及解压 Linux 进程 Linux运行tomcat Linux安装mysql 卸 ...

  7. Activiti工作流学习笔记(四)——工作流引擎中责任链模式的建立与应用原理

    原创/朱季谦 本文需要一定责任链模式的基础,主要分成三部分讲解: 一.简单理解责任链模式概念 二.Activiti工作流里责任链模式的建立 三.Activiti工作流里责任链模式的应用 一.简单理解责 ...

  8. JS基础学习第二天

    类型转换 类型转换就是指将其他的数据类型,转换为String Number 或 Boolean 转换为String 方式一(强制类型转换): 调用被转换数据的toString()方法例子:var a ...

  9. 【转载】C# get 与set的一些说明

    转载 在面向对象编程(OOP)中,是不允许外界直接对类的成员变量直接访问的,既然不能访问,那定义这些成员变量还有什么意义呢?所以C#中就要用set和get方法来访问私有成员变量,它们相当于外界访问对象 ...

  10. 零基础学Java,PayPal技术专家手把手带你入门

    在最权威的 TIOBE 编程语言排名榜单上,Java 常年稳居第一,可以说是世界上应用最为广泛的一门语言. 同时,在微服务.云计算.大数据.Android App 开发等领域,Java 也是当之无愧的 ...