版本说明
"MongoDB": "4.0.9", // cmd命令窗输入:mongo --version
"node": 10.13.0, // cmd命令窗输入:node -v
"npm": 6.10.3, // cmd命令窗输入:npm -v
"express": 4.16.0 // cmd命令窗输入:express --version
以下主要是 Mongodb 在 node.js 中的使用,通过对象模型工具 mongoose 操作数据库,操作数据库通过可视化工具 Robo 3T
一、在 node.js 中连接数据库的方式,通过命令 node app.js 运行启动文件即可
1.1、启动文件内容大致如下,其中引入的模板(中间件),需要通过 npm 进行安装
(一般通过 npm install xxxx --save:表示生产环境和开发环境都需要此包, npm install xxx --save-dev :表示开发环境需要此包)
1.2、定义启动文件 app.js
/**
* 启动express服务
*/
//1. 引入express模块
const express = require('express');
//2. 引入body-parser才能拿到post的参数
const bodyParser = require('body-parser');
//3. 引入定义的接口路由
const user = require('./router/users');
// 4. 引入cors包
var cors = require('cors');
// 5 .创建app对象
const app = express();
// 解决post接口获取为正常的application/json
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// 解决跨域问题
app.use(cors({
origin: ['http://localhost:8099'], // 允许指定域名访问
methods: ['GET', 'POST', 'PUT', 'DELETE'], // 允许指定请求方式
alloweHeaders: ['Content-Type', 'Authorization'], // 只允许带这两种请求头的链接访问
credentials: true // 允许跨域携带cookie值
}));
// 使用接口/路由
app.use('/user', user);
app.use('/', (req, res) => {
res.send('Oh you are success!!')
});
// 定义服务启动端口
app.listen(3000, () => {
console.log('app listening on port 3000')
})
二、获取数据表中的字段,通过封装数据模型 mongoose.Schema
2.1、定义封装数据表的文件 tableSchema.js
2.2、数据库中的 users 表如下
2.3、定义连接数据库,导出数据表等操作的文件 db.js
// 引入mongoose模块
const mongoose = require('mongoose');
mongoose.Promise = require('bluebird');
// 引入数据表
const tableSchema = require('./tableSchema');
/**
* 数据库地址(myUser 表示对应的数据库名)
* Connecting to Mongod instance.
*/
const dbHost = 'mongodb://localhost/myUser';
/**
* 连接mongodb数据库
* @param {参数1} 'mongodb数据库启动的地址'
* @param {参数2} 'parser过时,调用新的解析方法'
* @param {参数3} '回调函数,用于判断是否连接成功'
*/
mongoose.connect(
dbHost,
{
useNewUrlParser: true
},
err => {
if (err) console.log("**********【数据库连接失败】**********" + err);
else console.log("**********【数据库连接成功】**********");
});
const db = mongoose.connection;
db.on('error', function () {
console.error.bind(console, 'Database connection error HA');
})
db.once('open', function () {
console.log('The Database has connected HA');
})
module.exports = tableSchema; // 导出数据表
三、在定义接口逻辑中,通过对象模型 操作数据表,如以下 user.js 接口文件
【 以下是重点代码!!!
四、结合上述,以下就只写 操作数据库的代码
4.1、mongoose 中的查找 find ( 数据模型以 Users 为例,其中包含的字段如上,第二点的2.1 )
Users.find({})
.then( user => {
console.log(user)
})
.catch(err => {
console.log(`${err.name} : ${err.message}`)
})
4.2、mongoose 中的模糊查询 find
const nameReg = new RegExp('王二狗', 'i'); // 搜索条件、'i'不区分大小写
let page = 1;
let size = 10;
/**
* '$or' 通过字段 name 进行模糊查询
* '{ token : 0 }' 表示不显示 token 字段
* 'sort({ id : 1 })' 通过 id 进行正序排序
* 'skip( page * size ), limit( size )' 查询了第 10 条到第 20 条数据
*/
Users.find(
{
$or: [
{ name: {$regex: nameReg } }
]
},
{
token: 0
},
sort({ id : 1 }),
skip( page * size ),
limit( size )
)
.then( user => {
console.log(user)
})
.catch(err => {
console.log(`${err.name} : ${err.message}`)
})
4.3、mongoose 中的创建 create (一条:传对象 Object; 多条:传数组 Array )
let obj = { username: '张胖子', age: 16 }
// 增加一条数据
Users.create(obj)
.then( user => {
console.log(user)
})
.catch(err => {
console.log(`${err.name} : ${err.message}`)
})
let arr = [
{ username: '张胖子', age: 16 },
{ username: '蔡妍', age: 18 },
{ username: '李沁', age: 20 }
]
// 增加多条数据
Users.create(arr)
.then( user => {
console.log(user)
})
.catch(err => {
console.log(`${err.name} : ${err.message}`)
})
4.4、mongoose 中的更新 findOneAndUpdate
let newObj = { username: '蔡妍', age: 60 }
/**
* 条件是 username 等于 '蔡妍'
* ' $set ' 表示需要修改后的对象值,需要包含所有原本对象所需的字段,即根据 username 的值覆盖原对象
* ' {new: true} ' 表示返回修改后的对象值,不设置默认返回修改之前的数据
*/
Users.findOneAndUpdate(
{
username: newObj.username
},
{
$set: newObj
},
{
new: true
}
)
.then( user => {
console.log(user)
})
.catch(err => {
console.log(`${err.name} : ${err.message}`)
})
4.5、mongoose 中的删除 : findOneAndRemove(删除一条)、 deleteMany(删除多条)
let deleteName = '蔡妍'
/**
* 删除 username 等于 '蔡妍' 的一条数据
*/
Users.findOneAndRemove(
{
username: deleteName
}
)
.then( user => {
console.log(user)
})
.catch(err => {
console.log(`${err.name} : ${err.message}`)
})
let deleteName = '蔡妍'
/**
* 删除 username 等于 '蔡妍' 的所有数据 (多条数据)
*/
Users.deleteMany(
{
username: deleteName
}
)
.then( user => {
console.log(user)
})
.catch(err => {
console.log(`${err.name} : ${err.message}`)
})
五、mongoose 中的其他操作(如 创建临时表、多表查询等)
5.1、mongoose 中的创建临时表 :通过聚合( aggregate )处理数据,参考官方文档
【 如 权限表 permission ,表中的字段如下】
【 在对应的 node.js 项目中,引入权限表的相关数据等 】
【 用 aggregate 创建一个临时表,获取权限表 permission 中的 children 字段中数据 ,参考官方文档】
/** * 【创建权限临时表】 * "$unwind" 如 将有字段是一个children数组( 包含三个元素 )的数据,返回以children为字段名,当前children字段的数据 对应 之前children数组下的元素,即一条数据替换成三条数据 * "$group" 需要以"_id"进行分组,定义"_id"对应的字段 ( 临时表拥有字段: _id、perm ) * "$push" 将"children"字段下的数据,作为元素添加到 "perm" 数组中 * "$sort" 以"_id"进行正序排序 ( "1"表示正序,"-1"表示倒序 ) * "$out" 输出临时表的名字 */ Permission.aggregate( [ { "$unwind": "$children" }, { $group: { _id: "$children.id", perm: { $push: "children" } } }, { $sort: { _id: 1 } }, { $out: "temp_perm" } ] ) .then( tempPerm => { // 创建成功后返回一个空数组 console.log(tempPerm) }) .catch(err => { console.log(`${err.name} : ${err.message}`) })
【 临时表在数据库显示如下,即 之前 children下的每个元素,组成了一条数据 】
5.2、mongoose 中的多表查询,通过聚合( aggregate )处理数据,参考官方文档 ( 以下说明了两张表、三张表的操作 )
两张表!!
- 【 需求:
- 【 思路: 用户表 users 和 用户角色表 users_roles, 其中的关联是,用户表 usres 中的字段 id ,与用户角色表 users_roles 的字段 user_id 一致( user_id 是外键,即类似对象中 users["id"] = users_roles["user_id"] = 3 ) 】 其中 "$lookup"参考这里
- 【 两张表在数据库中的字段定义如下: 】
let id = 3; /** * 聚合(aggregate)主要用于处理数据,并返回计算后的数据结果,有点类似sql语句中的 count(*) * "$project" 只显示(1)或隐藏(0)对应属性 * "$match" 用于过滤数据,只输出符合条件的文档,此处是 只输出 id=3 的数据 * "$lookup" 根据主外键联表查询(外键是相对主表中的字段名,此处是 user_id) * "from" 表示 在同一数据库中指定要执行联接的集合。 * "localField" 表示 指定从文档输入到$ lookup阶段的字段。即 users 表对应的主键。 $lookup在from集合的文档中对localField和foreignField执行相等的匹配。 * "foreignField" 表示 指定from集合中文档中的字段。即 users_roles 表对应的外键 * "as" 表示 指定要添加到输入文档中的新数组字段的名称。 */ Users.aggregate([ { "$project": { "__v": 0 } }, { "$match": { "id": id } }, { $lookup: { from: 'users_roles', localField: "id", foreignField: "user_id", as: "users_roles" } } ]) .then( user => { console.log(user) }) .catch(err => { console.log(`${err.name} : ${err.message}`) })
三张表!!!
- 【 需求:
- 【 思路:已知用户角色表 users_roles["user_id"] = 3,其中三张表中的关联如下,用户角色表 users_roles 与 角色权限表 role_permission:users_roles["role_id"] = role_permission["role_id"] ,角色权限表 role_permission 和 权限表 permission:role_permission["permission_id"] = permission["id"] 】
- 【 三张表在数据库中的字段定义如下: 】
let id = 3;
/**
* 聚合(aggregate)主要用于处理数据,并返回计算后的数据结果,有点类似sql语句中的 count(*)
* "$project" 只显示(1)或隐藏(0)对应属性
* "$match" 用于过滤数据,只输出符合条件的文档,此处是 只输出 id=3 的数据
* "$lookup" 根据主外键联表查询(外键是相对主表中的字段名,此处是 user_id)
* "from" 表示 在同一数据库中指定要执行联接的集合。
* "localField" 表示 指定从文档输入到$ lookup阶段的字段。如 users_roles 表对应的主键。 $lookup在from集合的文档中对localField和foreignField执行相等的匹配。
* "foreignField" 表示 指定from集合中文档中的字段。如 role_permission 表对应的外键
* "as" 表示 指定要添加到输入文档中的新数组字段的名称。
*/
UsersRoles.aggregate([
{ "$match": { "user_id": id } },
{
$lookup: {
from: 'role_permission',
localField: "role_id",
foreignField: "role_id",
as: "inventory_permission"
}
}, {
$lookup: {
from: 'permission',
localField: "inventory_permission.permission_id",
foreignField: "id",
as: "permission_detail"
}
}
])
.then( user => {
console.log(user)
})
.catch(err => {
console.log(`${err.name} : ${err.message}`)
})
总结:
- 1、首先建立mongodb数据库和数据表,可以通过可视化工具 Robo 3T
- 2、然后运行node服务器项目,选择Mongoose操作数据库(Mongoose 是MongoDB的一个对象模型工具)
- 3、通过 mongoose 连接数据库,定义数据表模型(需要的字段在此定义,若没定义获取不到)
- 4、然后通过 mongoose 在 node.js 中的语法,操作数据库,参考官方文档
- 5、写给自己的随笔,有问题欢迎指出(Θ▽Θ)