初入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开发前 ...
随机推荐
- 关于win10 编辑文件时权限不足问题
win10默认是不开启administrator账户的,所以一般是自己创建一个账户,但是此账户,可能会有些文件或文件夹,访问不了,编辑不了,这时候,只需要右键->属性->安全->编辑 ...
- Codeforces Round #548 C. Edgy Trees
题面: 传送门 题目描述: 给出有n个节点的树,整数k.题目要求找长度为k,符合规则(good序列)的"点序列"(由节点构成的序列)个数有多少?规则如下: 1.走一条出发点为a1, ...
- Python之基础算法介绍
一.算法介绍 1. 算法是什么 算法是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制.也就是说,能够对一定规范的输入,在有限时间内获得所要求的输 ...
- 世界国省市区SQL语句(mysql)
CREATE TABLE loctionall ( country VARCHAR(40) , provice VARCHAR(40) , city VARCHAR(40) , CONSTRAINT ...
- 剑指 Offer 03. 数组中重复的数字
剑指 Offer 03. 数组中重复的数字 找出数组中重复的数字. 在一个长度为 n 的数组 nums 里的所有数字都在 0-n-1 的范围内.数组中某些数字是重复的,但不知道有几个数字重复了,也不知 ...
- CentOS7使用NTP搭建时间同步服务器
前言 为什么要搭建时间同步服务器呢?场景是这样的. 我们有两台CentOS服务器,其中一台是可以连接外网的,下文中我们称它为A服务器,另一台不能连接外网,但是与A服务器在同一局域网中,下文中我们称它为 ...
- java例题_08 输入特定数字求和(n个a位数递增求和问题)
1 /*8 [程序 8 输入数字求和] 2 题目:求 s=a+aa+aaa+aaaa+aa...a 的值,其中 a 是一个数字.例如 2+22+222+2222+22222(此时共有 5 个数相加), ...
- PAT (Basic Level) Practice (中文)1055 集体照 (25 分) 凌宸1642
PAT (Basic Level) Practice (中文)1055 集体照 (25 分) 凌宸1642 题目描述: 拍集体照时队形很重要,这里对给定的 N 个人 K 排的队形设计排队规则如下: 每 ...
- 使用Vscode 开发调试 C/C++ 项目
需要安装的扩展 C/C++ 如果是远程 Linux上开发还需要安装 Remote Development 创建工作目录后,代码远程克隆... 省略.. 创建项目配置文件,主要的作用是代码智能提示,错误 ...
- SpringBoot 集成测试
一. 测试一般程序(Service/DAO/Util类) 1. 在pom.xml中引入依赖 2. 生成测试类 <1> 如果使用IntelliJ IDEA,可以使用快捷键直接生成: Wind ...