通过 Mongoose 使用 MongoDB —— 在 Express 中

安装 Mongoose 与 MongoDB

安装 MongoDB

以下展示在 macOS 中使用 Homebrew 安装 MongoDB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 安装 MongoDB
$ brew install mongodb

// 配置数据库
$ sudo mkdir -p /data/db
$ sudo chown -R $USER /data/db

// 配置环境变量(以zsh为例)
$ vim ~/.zshrc

# MongoDB
export PATH=${PATH}:/usr/local/mongodb/bin

$ source ~/.zshrc
启动 MongoDB
1
2
3
4
5
// 启动服务端
$ mongod

// 启动 shell
$ mongo
安装 Mongoose
1
$ npm install mongoose

连接到 MongoDB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 导入 mongoose 模块
const mongoose = require('mongoose');

// 设置默认 mongoose 连接
const mongoDB = 'mongodb://127.0.0.1/database_name';
mongoose.connect(mongoDB);

// 让 mongoose 使用全局 Promise 库
mongoose.Promise = global.Promise;
// 取得默认连接
const db = mongoose.connection;

// 将连接与错误事件绑定(以获得连接错误的提示)
db.on('error', console.error.bind(console, 'MongoDB 连接错误:'));

Schema 与 Model

Schema

使用Schema定义documents的结构。(其实就是表结构

下面是一个定义好的Schema示例:

1
2
3
4
5
6
7
8
9
10
11
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const exampleSchema = new Schema({
title: String,
author: String,
living: Boolean,
updated: {type: Date, default: Date.now},
age: {type: Number, min: [18, '你未成年啊!'], max: 65, required: true},
_someId: Schema.Types.ObjectId
})

事实上,你可以直接参阅官方的 SchemaType 文档

附加
  1. 虚拟属性
    简单来说,这就是个过滤器,可以过滤gettersetter
    getter 可以格式化或组合字段以便于输出。setter 可以将单个值分解为多个值以便于存储

    1
    2
    3
    4
    5
    6
    7
    8
    personSchema.virtual('fullName')
    .get(() => {
    return this.name.first + ' ' + this.name.last;
    })
    .set((n) => {
    this.name.first = n.substr(0, v.indexOf(' '));
    this.name.last = n.substr(v.indexOf(' ') + 1);
    })
  2. 方法和查询助手

    待续

使用模型

你可以使用以及定义好的模式来创建模型。模型是数据库中可以搜索的一类文档,模型的实例即可以存取的单个文档

以下是基础的代码示例:

  • Constructing Documents

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // 编辑 Model
    const schema = new mongoose.Schema({ name: 'string', size: 'string'});
    const Tank = mongoose.model('Tank', schema);

    // 创建 Documents
    const small = new Tank({ size: 'small' });
    small.save((err) => {
    if (err) {
    return handleError(err);
    // saved
    }
    })

    Tank.create({size: 'small'}, (err, small) => {
    if (err) {
    return handleError(err);
    // saved
    }
    })

    // 插入大量数据至 documents
    Tank.insertMany([{size: 'small'}], (err) => {});
  • 操作

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // Querying
    Tank.find({size: 'small'}).where('createdDate').gt(oneYearAgo).exec(callback);

    // Deleting
    Tank.deleteOne({size: 'large'}, (err) => {
    if (err) {
    return handleError(err);
    // deleted at most one tank document
    }
    })

    // Updating
    Tank.updateOne({size: 'large'}, {name: 'T-90'}, (err, res) => {
    // Updated at most one doc, `res.modifiedCount` contains the numer
    // of docs that MongoDB updated
    })
文档间协同

待续

关于一模式(模型)一文件

因为框架本身对文件结构几乎没有限制,过于松散的代码会导致困难的维护,所以建议将单一模式定义在单一模块(文件)中,并通过带出方法来创建模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/* ./models/somemodel.js */

// Require Mongoose
const mongoose = require('mongoose');

// 定义一个模式
const Schema = mongoose.Schema;

const SomeModelSchema = new Schema({
a_string: String,
a_date: date
});

// 导出函数来创建 SomeModel 模型类
module.exports = mongoose.model('SomeModel', SomeModelSchema);


/* ./?.js */

// 通过 require 模块来创建 SomeModel 模型
const SomeModel = require('../models/somemodel')

// 使用 SomeModel 对象(模型)来查找所有的 SomeModel 记录
SomeModel.find(callback_function);