创建集合分为两步,一是对对集合设定规则,二是创建集合,创建mongoose.Schema构造函数的实例即可创建集合。
// 创建集合规则
const courseSchema = new mongoose.Schema({
name: String,
anthor: String,
isPublished: Boolean
})
// 使用规则创建集合
// 1.集合名称
// 2.集合规则
const Course = mongoose.model('Course', courseSchema);
创建文档实际上就是向集合中插入数据。 分为两步: 创建集合实例。 调用实例对象下的save方法将数据保存到数据库中。
const course = new Course({
name// 如果想要向集合中插入数据 那么需要创建集合构造函数的实例
// 创建文档
const course = new Course({
name: 'node.js基础',
anthor: '小蒙',
isPublished: 'true'
})
// 将文档插入数据库中
course.save();: 'node.js基础',
anthor: '小蒙',
isPublished: 'true'
})
course.save();
数据库的所有操作都是异步操作
1.使用create方法创建文档 通过回调函数的方法获取异步API
// 向集合中插入文档
Course.create({
name: 'JavaScript',
anthor: "小蒙",
isPublished: false
}, (err, result) => {
console.log(err);
console.log(result);
})
Course.create({
name: 'vue',
anthor: "小蒙",
isPublished: false
})
.then(err => {
console.log(err);
})
.catch(result => {
console.log(result);
})
create方法能够返回promise对象,说明也支持异步函数的语法
找到mongodb数据库的安装目录,将安装目录下的bin目录放置在环境变量中。
mongoimport –d 数据库名称 –c 集合名称 –file 要导入的数据文件
显示如下结果表示导入文件成功:
显示如下结果表示导入文件成功:
// 根据条件查找文档(条件为空则查找所有文档)
Course.find().then(result => console.log(result))
//通过_id字段查找文档
// User.find({
// _id: '5c09f1e5aeb04b22f8460965'
// }).then(result => console.log(result));
返回一个数组
// 根据条件查找文档
Course.findOne({name: 'node.js基础'}).then(result => console.log(result))
返回一个对象
匹配大于小于等于
User.find({age: {
匹配包含
User.find({hobbies: {$in: ['足球']}}).then(result => console.log(result))
选择要查询的字段
User.find().select('name email').then(result => console.log(result))
不想要的值在字段后面添加 - 再加属性 比如去掉默认的_id
User.find().select('name email -_id').then(result => console.log(result))
将数据按照年龄进行升序排序
User.find().sort('age').then(result => console.log(result))
将数据按照年龄进行降序排序
User.find().sort('-age').then(result => console.log(result))
skip 跳过多少条数据 limit 限制查询数量
User.find().skip(2).limit(3).then(result => console.log(result))
上面的代码表示的是 跳过前两条数据 并且只保留三个数据
删除单个文档
查找到一条文档并且删除
返回删除的文档
如何查询条件匹配了多个文档那么将会删除第一个匹配的文档
User.findOneAndDelete({_id: '5c09f1e5aeb04b22f8460965'}).then(result => console.log(result));
删除多个文档 如果没有给出删除的文档 那么将删除所有文档
User.deleteMany({}).then(result => console.log(result));
更新单个文档
User.updateOne({name:'张三'},{name:'张三丰'}).then(result => console.log(result))
原来的数据库
更新过后的数据库
更新多个文档
User.updateMany({}, {name: '张三丰'}).then(result => console.log(result))
更新前
更新后
mongoose验证
在创建集合规则时,可以设置当前字段的验证规则,验证失败就则输入插入失败。
获取错误信息:error.errors['字段名称'].message
// 创建集合规则
const postSchema = new mongoose.Schema({
title: {
// type: String,
// require: true,
// trim: true,
// minlength: 2,
// maxlength: 5
type: String,
require: [true, '标题不能为空'],
trim: [true, '去除标题两侧的空格'],
minlength: 2, // 最小不能少于两个字符
maxlength: 5 // 最多不能超过5个字符串
},
age: {
type: Number,
min: 18,
max: 25
},
publishDate: {
type: Date,
default: Date.now
},
category: {
type: String,
//枚举列举出当前字段可以拥有的值
enum: ['html', 'css', 'Javascript', 'node.js']
},
anthor: {
type: String,
validate: {
validator: v => {
//返回布尔值l
// true 验证成功
// false验证失败
// v 要验证的值
return v && v.length > 4
},
// 自定义错误信息
message: '传入的值不符合验证规则'
}
}
})
const post = mongoose.model('Post', postSchema);
post.create({
title: '你好,世界',
age: 19,
category: 'css',
anthor: '今天也要加油呀'
}).then(result => console.log(result));
通常不同集合的数据之间是有关系的,例如文章信息和用户信息存储在不同集合中,但文章是某个用户发表的,要查询文章的所有信息包括发表用户,就需要用到集合关联。
集合关联实现
// 用户集合
const User = mongoose.model('User', new mongoose.Schema({ name: { type: String } }));
// 文章集合
const Post = mongoose.model('Post', new mongoose.Schema({
title: { type: String },
// 使用ID将文章集合和作者集合进行关联
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
}));
//联合查询
Post.find()
.populate('author')
.then((err, result) => console.log(result));
2.实现用户修改功能
实现代码:
user.js
const mongoose = require('mongoose');
// 创建用户集合规则
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
minlength: 2,
maxlength: 15
},
age: {
type: Number,
min: 18,
max: 80
},
password: String,
email: String,
hobbies: [String]
});
//创建集合返回集合构造函数
const User = mongoose.model('User', userSchema);
module.exports = User;
index.js
const mongoose = require('mongoose');
// 数据库连接 27017是mongodb数据库的默认端口
mongoose.connect('mongodb://localhost/playground', {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => console.log('数据库连接成功'))
.catch(() => console.log('数据库连接失败'));
app.js
const http = require('http');
const url = require('url');
// 引入字符串方法
const querystring = require('querystring');
require('./model/index');
const User = require('./model/user');
// 创建服务
const app = http.createServer();
// 为服务器对象添加请求事件
app.on('request', async (req, res) => {
// res.end('list');
// 请求方式
const method = req.method;
// 请求地址
const {
pathname,
query
} = url.parse(req.url, true);
if (method == 'GET') {
// 呈现用户列表页面
if (pathname == '/list') {
// 查询用户信息
let users = await User.find();
// html字符串
console.log(users);
let list = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h6>
<a href="/add" class="btn btn-primary">添加用户</a>
</h6>
<table class="table table-striped table-bordered">
<tr>
<td>用户名</td>
<td>年龄</td>
<td>爱好</td>
<td>邮箱</td>
<td>操作</td>
</tr>
`;
users.forEach(item => {
list += `
<tr>
<td>${item.name}</td>
<td>${item.age}</td>
<td>
`;
item.hobbies.forEach(item => {
list += `<span>${item}</span>`;
});
list += `
</td>
<td>${item.email}</td>
<td>
<a href="/remove?id=${item._id}" class="btn btn-danger btn-xs">删除</a>
<a href="/modify?id=${item._id}" class="btn btn-success btn-xs">修改</a>
</td>
</tr>`;
})
list += `
</table>
</div>
</body>
</html>
`;
res.end(list);
} else if (pathname == '/add') {
// 呈现添加用户界面
let add = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h3>添加用户</h3>
<form method = "post" action="/add">
<div class="form-group">
<label>用户名</label>
<input type="text" name="name" class="form-control" placeholder="请填写用户名">
</div>
<div class="form-group">
<label>密码</label>
<input type="password" name="password" class="form-control" placeholder="请输入密码">
</div>
<div class="form-group">
<label>年龄</label>
<input type="age" name="age" class="form-control" placeholder="请输入年龄">
</div>
<div class="form-group">
<label>邮箱</label>
<input type="email" name="email" class="form-control" placeholder="请填写邮箱">
</div>
<div class="form-group">
<label>请选择爱好</label>
<div>
<label class="checkbox-inline">
<input type="checkbox" value="足球" name="hobbies">足球
</label>
<label class="checkbox-inline">
<input type="checkbox" value="篮球" name="hobbies"> 篮球
</label>
<label class="checkbox-inline">
<input type="checkbox" value="橄榄球 name="hobbies"> 橄榄球
</label>
<label class="checkbox-inline">
<input type="checkbox" value="敲代码 name="hobbies"> 敲代码
</label>
<label class="checkbox-inline">
<input type="checkbox" value="抽烟" name="hobbies"> 抽烟
</label>
<label class="checkbox-inline">
<input type="checkbox" value="喝酒" name="hobbies"> 喝酒
</label>
<label class="checkbox-inline">
<input type="checkbox" value="烫头" name="hobbies"> 烫头
</label>
</div>
</div>
<button type="submit" class="btn btn-primary">添加用户</button>
</form>
</div>
</body>
</html>
`;
res.end(add);
} else if (pathname == '/modify') {
// 呈现修改用户界面
let user = await User.findOne({
_id: query.id
});
let hobbies = ['足球', '篮球', '橄榄球', '敲代码', '抽烟', '喝酒', '烫头', '吃饭', '睡觉', '打豆豆'];
console.log(user);
let modify = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户列表</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<h3>修改用户</h3>
<form method = "post" action="/modify?id=${user._id}">
<div class="form-group">
<label>用户名</label>
<input type="text" value="${user.name}" name="name" class="form-control" placeholder="请填写用户名">
</div>
<div class="form-group">
<label>密码</label>
<input type="password" value="${user.password}" name="password" class="form-control" placeholder="请输入密码">
</div>
<div class="form-group">
<label>年龄</label>
<input type="age" value="${user.age}" name="age" class="form-control" placeholder="请填写年龄">
</div>
<div class="form-group">
<label>邮箱</label>
<input value="${user.email}" type="email" name="email" class="form-control" placeholder="请填写邮箱">
</div>
<div class="form-group">
<label>请选择爱好</label>
<div>
`;
hobbies.forEach(item => {
//判断当前循环项在不在用户的爱好数据组
let isHooby = user.hobbies.includes(item);
if (isHooby) {
modify += `
<label class="checkbox-inline">
<input type="checkbox" value="${item}" name="hobbies" checked> ${item}
</label>
`;
} else {
modify += `
<label class="checkbox-inline">
<input type="checkbox" value="${item}" name="hobbies"> ${item}
</label>
`;
}
})
modify += `
</div>
</div>
<button type="submit" class="btn btn-primary">修改用户</button>
</form>
</div>
</body>
</html>
`;
res.end(modify);
} else if (pathname == '/remove') {
// res.end(query.id);
await User.findOneAndDelete({
_id: query.id
});
// 重定向
res.writeHead(301, {
Location: '/list'
});
res.end();
}
} else if (method == 'POST') {
//用户添加功能
if (pathname == "/add") {
// 接受用户提交的信息
let formData = '';
// 接受post参数
req.on('data', param => {
formData += param;
});
// 接受post参数完毕
req.on('end', async () => {
let user = querystring.parse(formData);
//将用户提交的信息添加到数据库中
await User.create(user);
// 301代表重定向
// Location 跳转地址
res.writeHead(301, {
Location: '/list'
});
res.end();
});
} else if (pathname == '/modify') {
// 接受用户提交的信息
let formData = '';
// 接受post参数
req.on('data', param => {
formData += param;
});
// 接受post参数完毕
req.on('end', async () => {
let user = querystring.parse(formData);
//将用户提交的信息添加到数据库中
await User.updateOne({
_id: query.id
}, user);
// 301代表重定向
// Location 跳转地址
res.writeHead(301, {
Location: '/list'
});
res.end();
})
}
}
})
// 监听事件
app.listen(3000);
console.log('网站服务器启动成功');