初入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. web图像化服务管理工具

    在 CentOS 8 中安装 Cockpit Web 控制台 Cockpit 是红帽开发的网页版图像化服务管理工具,优点是无需中间层,且可以管理多种服务. 根据其项目主站描述,Cockpit 有如下特 ...

  2. Python爬虫学习三------requests+BeautifulSoup爬取简单网页

    第一次第一次用MarkDown来写博客,先试试效果吧! 昨天2018俄罗斯世界杯拉开了大幕,作为一个伪球迷,当然也得为世界杯做出一点贡献啦. 于是今天就编写了一个爬虫程序将腾讯新闻下世界杯专题的相关新 ...

  3. centos /bin /sbin /usr/bin /usr/sbin 目录的说明

    在linux下我们经常用到的四个应用程序的目录是/bin./sbin./usr/bin./usr/sbin .而四者存放的文件一般如下:    bin目录:  bin为binary的简写主要放置一些系 ...

  4. java例题_36 移动数组中数据位置(用到数组的合并操作)

    1 /*36 [程序 36 移动位置] 2 题目:有 n 个整数,使其前面各数顺序向后移 m 个位置,最后 m 个数变成最前面的 m 个数,比如输入数字 3 为 1 2 3 4 5 6 7 8 9 0 ...

  5. 以聊天的形式解决traefik2.1.X的一个问题

    海口-老男人 17:24:48 大哥,这个是啥报错呀 海口-老男人 17:27:04 E0413 09:23:13.134144 1 reflector.go:153] pkg/mod/k8s.io/ ...

  6. VIM 编辑器操作详解

    1 vim 使用介绍 1.1 vim 安装 # CentOS 安装: yum install -y vim # Ubuntu 安装: sudu apt-get install vim 安装完成后,可使 ...

  7. A. 【例题1】数字反转

    题目解析 字符串的基础操作,注意判断零即可 #include <bits/stdc++.h> using namespace std; int i; char c[15]; int mai ...

  8. ADFS修改默认访问端口

    在安装Dynamics CRM部署IFD需要安装ADFS来进行身份验证.而ADFS默认会占用服务器的443端口.如果我们想自己使用443端口的话则需要修改ADFS的默认端口.(如果需要部署移动端的话还 ...

  9. Dynamics CRM安装教程四:DNS配置

    在为MS CRM 配置Claims-based认证之前,你需要在域控服务器的DNS中添加一些记录,来解析CRM的各个断点,添加內容如下(本次环境全部安装在一台机子中): AD FS 服务器(例: ad ...

  10. B1029/A1048 旧键盘损坏了,在输入一段文字时坏了的键不可以正常使用,现给出应输入的一段文字,和实际输出的文字,找出坏掉的键。

    #include<cstdio> #include<cstring> const int maxn = 1000; bool HashTable[maxn] = { false ...