初入MongoDB
初入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的更多相关文章
- 初入SG-UAP
初入SG-UAP SpriderMan 关注 2019.06.19 14:10 字数 1130 阅读 10评论 0喜欢 0 初次接触SG-UAP,将自己的见解以文字形式记录下来,希望能对初入的伙伴们有 ...
- Scala初入
何为Scala物 Scala为基于JVM虚拟机中的面向对象与函数式编程思想并且完全兼容Java的混合编程语言,可以是Scala与Java是同根同源的,既然Scala与JAVA都是基于JVM之上的编程语 ...
- 初学HTML5、初入前端
学习HTML5是一个漫长的过程,当中会遇到很多技术与心态上的变化.刚开始学习,我们不能发力过猛,需要一个相对稳定的状态去面对.多关注一些自己感兴趣的网站和技术知识,建立自己的信心与好奇心,为以后的学习 ...
- 0x00linux32位汇编初入--前期准备
0x00汇编初入--前期准备 一.汇编工具 在linux平台下常用的编译器为as,连接器为ld,使用的文本编辑器为vim,汇编语法为att 以下是一些工具: addr2line 把地址转换为文件名和行 ...
- 初入职场的建议--摘自GameRes
又开始一年一度的校招了,最近跑了几个学校演讲,发现很多话用短短的一堂职业规划课讲还远远不够,因为那堂课仅仅可能帮大家多思考怎样找到一份合适的工作,并没有提醒大家怎样在工作中发展自己的职业. 见过这么多 ...
- 【Xbox one S】开箱&开机&初入坑心得
再来一发水贴,先上产品标准照镇贴: 前言 身为一个资深单机游戏玩家,常年混迹在PC平台,但内心深处一直对主机有种迷之向往,感觉那才是单机游戏的正处之地,坐沙发上拿着手柄对着电视跌宕起伏才是正确的游戏姿 ...
- Git初入
Git记录 使用git 也有一段时间了, git的入门级了解也就不再多说, 但平常使用中, 仍然会遇到很多问题, 在此记录一二. 在查资料的过程中, 发现了两个比较好的资料: 特别是第二个, 相当详细 ...
- SuperMap iClient for JavaScript初入
SuperMap iClient for JavaScript初入 介绍SuperMap for Js的简单使用. 推荐先看下这篇文档:SuperMap iClient for JavaScript ...
- 初入前端框架bootstrap--Web前端
Bootstraps是一种简洁.直观.强悍的前端开发框架,它让web开发更迅速.简单.对于初入Bootstrap的小白,高效进入主题很重要,能为我们节省很多时间,下面我将对使用Bootstrap开发前 ...
随机推荐
- [LOJ 572] Misaka Network 与求和
一.题目 点此看题 二.解法 直接推柿子吧: \[\sum_{i=1}^n\sum_{j=1}^nf(\gcd(i,j))^k \] \[\sum_{d=1}^nf(d)^k\sum_{i=1}^{n ...
- MySql多表查询_事务_DCL(资料三)
今日内容 1. 多表查询 2. 事务 3. DCL 多表查询: * 查询语法: select 列名列表 from 表名列表 where.... * 准备sql # 创建部门表 CREATE TABLE ...
- android消息线程和消息队列
基于消息队列的线程通信: 消息队列与线程循环 MessageQueue: 利用链表来管理消息. Mess ...
- .Net Core3.1中SameSite的使用方法、遇到的问题以及解决办法
一.关于SameSite的介绍 1. 什么是SameSite? SameSite是浏览器请求中Set-Cookie响应头新增的一种属性,它用来标明这个 cookie 是否是"同站 cook ...
- Android学习中出现的问题
•问题1:多行文字如何实现跑马灯效果? 博客链接:Androidd Studio 之多行文字跑马灯特效 解决状态:已解决 •问题2:cause: unable to find valid certif ...
- [树形DP]电子眼
电 子 眼 电子眼 电子眼 题目描述 中山市石一个环境优美.气候宜人的小城市.因为城市的交通并不繁忙,市内的道路网很稀疏.准确地说,中山市有N-1条马路和N个路口,每条马路连接两个路口,每两个路口之间 ...
- 【数据结构与算法笔记04】对图搜索策略的一些思考(包括DFS和BFS)
图搜索策略 这里的"图搜索策略"应该怎么理解呢? 首先,是"图搜索",所谓图无非就是由节点和边组成的,那么图搜索也就是将这个图中所有的节点和边都访问一遍. 其次 ...
- String类的使用2
/*String:字符串,使用一对""引起来表示.1.String声明为final的,不可被继承2.String实现了Serializable接口:表示字符串是支持序列化的. 实现 ...
- badusb论述
"BadUSB"是2014年计算机安全领域的热门话题之一,该漏洞由Karsten Nohl和Jakob Lell共同发现 攻击原理 TEENSY 攻击者在定制攻击设备时,会向USB ...
- keepalived安装及组合nginx配置负载实现高可用
目录 1. Keepalived安装配置 1.1 官网下载tar包 1.2 上传到指定目录安装 1.3 配置文件 1.4 配置nginx检测脚本文件 1.5 keepalived 启动/重启/停止/查 ...