在node上搭建一个mongodb服务器
前言
由于Cloud Studio中每个工作空间只能使用1G的内存,当后台运行进程过多时,如果当前运行的进程需要比较多的内存时,就会造成该进程『killed』(由于可用内存不够导致内存溢出);比如使用npm run dev或npm run build时,被kill时就会报一个137的错误,对于node可以通过设置--max-old-space-size来限制node或npm本身占用的最大内存;但是限制内存后程序自然就运行得慢了。
而像mongodb这种进程在后台运行肯定会占用较多的内存,因此决定将其单独设立到另一个主机空间,做成远程服务器(即不是集成到当前空间和项目中,而是利用ip或网址进行访问,就是调用API接口的形式)进行连接。
准备工作
要使用mongodb光在node项目中引入相关依赖包是不够的,因为那些包只是对mongodb数据库进行连接和操作的!!!所以,首先必须在主机空间里安装mongodb软件。
安装mongodb
- 由于
Cloud Studio给定的主机是Ubuntu 16.04 x64的,所以需要去Mongodb官网下载中心选择对应系统版本的安装包,然后下载,如: 
1  | wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-ubuntu1604-3.6.7.tgz  | 
- 下载完安装包后,进行解压:
 
1  | tar -xvf mongodb-linux-x86_64-ubuntu1604-3.6.7.tgz  | 
解压后顺便把文件夹名称一改,因为这文件夹名实在是有点长:
1  | mv mongodb-linux-x86_64-ubuntu1604-3.6.7 mongodb  | 
现在相当于把mongodb安装在~/path/mongodb文件夹下了。
- 添加到环境变量中:
 
由于studio使用的命令行是zsh,所以需要在~/.zhsrc的末尾添加:
1  | export MONGODB_HOME="$HOME/path/mongodb"  | 
添加完后执行更新命令:
1  | source .zshrc  | 
然后就可以使用mongodb的命令了。
启动mongodb数据库
启动一个mongodb数据库,需要给定一个存放数据库文件的文件夹路径;比如在~下新建了一个dbdata文件夹,然后指定为数据库文件存放路径并启动mongodb数据库:
1  | mongod -dbpath=./dbdata  | 
启动的数据库默认端口是27017,如果要使数据库一直保持运行(后台运行),可以在启动命令的最后添加&即可。
搭建Express服务器
显然,只有数据库是无法完成API接口的;因此需要一个用来接收request,返回response的服务器组件。经过一番查询后,发现在Node.js使用较多的是Express这个服务器框架,看了一下确实比较方便,只需要关心输入输出即可,不需要考虑太多的配置,所以决定搭建一个Express服务器来处理request和response。
安装依赖
1  | npm i express -S  | 
简单的Express服务器
在项目文件夹创建一个app.js文件,然后写一个简单的处理request和response的服务器:
1  | const express = require('express')  | 
上面的代码就相当于建立了一个服务器,这个服务器的地址就是0.0.0.0:3000;然后当使用get方法访问服务器根路径/时,给出的response正文为Hello World!。
使用node app.js启动服务器,访问效果如下:

Mongoose
由于node并不能直接连接mongodb服务器进行数据获取和操作,因此需要能够在node下对mongodb服务器进行操作的工具。事实上mongodb官方早就实现了基于Node.js的驱动和API,只需要在node项目中安装mongodb这个依赖包就可以实现对mongodb服务器的连接和操作;但是由于对数据结构没有限定,使用比较自由,所以觉得另一个基于官方驱动的mongoose更符合我的胃口,因为mongoose的Schema可以实现对数据的结构和数据类型进行限定。
安装
1  | npm i mongoose -S  | 
连接数据库
1  | const mongoose = require('mongoose')  | 
显然,所有的CRUD操作肯定需要在连接成功事件(open)内进行。
Schema、model和document
由于mongodb属于nosql类型数据库,对于数据库中的表(在mongodb中并没有表这一说,相对应的是集合(collection),一个集合并没有数据结构和类型限制,集合内的数据并不需要格式相同);而Schema算是mongoose对于mongodb没有限定集合内数据结构和类型的补充,而model可以看做具有给定Schema的集合,而docuement则是model的实例,可以看做是该集合内的一条数据。

Schema
Schema以键值对的形式来定义数据结构和类型,键名就是字段名称,而值就是类型限制或更加详细的设定;其中可以使用的数据类型有:
- String
 - Number
 - Date
 - Buffer
 - Boolean
 - Mixed:
Schema.Types.Mixed,实际上就相当于一个Object;这种类型无法对其内部数据类型进行准确限定! - ObjectId
 - Array:数组内元素类型可以是
Schema或其它数据类型 - Decimal128
 - Schema:一个已经被定义的
Schema可以作为一种类型使用,也就是Schema可以嵌套! 
P.s:当某个字段的类型为一个对象,且对象的字段全都给定了类型限定,则会被自动转为一个Schema作为该字段的类型!
实例:
1  | const mongoose = require('mongoose')  | 
model,document
1  | // 按给定数据结构和类型生成Schema,并绑定到指定集合  | 
事实上,Schema只是格式,真正具有CRUD的是model和document;而model具有最直接的数据操作。
收尾
简单地来说:mongodb数据库也有了,Express服务器也有了,剩下的就是在相应的路由里由mongoose连接数据库进行CRUD操作,并在response中返回相应的数据,这样就构成了一个完整的API服务器了。