On this page
链接数据库
//导入Mongoose包
const mongoose = require('mongoose');
//链接MongoDB
mongoose.connect('mongodb://localhost:27017/bilibili');
//设置回调
mongoose.connection.once('open', () => {
console.log('链接数据库成功');
});
mongoose.connection.once('error', () => {
console.log('链接数据库失败');
});
mongoose.connection.once('close', () => {
console.log('和数据库的链接中断');
});
setTimeout(() => {
mongoose.disconnect();
}, 2000);
once和on的区别在于once只会执行一次回调函数,而on会每次都执行,如果将端口侦听写在回调中,则一定要用once。
创建新文档
mongoose.connection.once('open', () => {
console.log('链接数据库成功');
//创建文档的结构对象,设置集合中文档的属性以及属性值类型
let bookSchema = new mongoose.Schema({
name: String,
author: String,
price: Number
});
//创建模型对象,即对之前的文档操作的封装对象
let bookModel = mongoose.model('books', bookSchema);
//新增
createBook(bookModel);
//bookModel.create({name: '西游记', author: '吴承恩',price: 19.9});
});
异步执行写入操作,返回插入数据对象本身。
这里原本可以卸载create的回调函数中,但是从Mongoose7开始create方法不在支持回调函数,因此只能通过异步操作方式获得返回对象。
async function createBook(bookModel){
try{
const data = await bookModel.create({ name: '红楼梦', author: '曹雪芹', price: 19.9 });
console.log(data);
}catch (err){
console.log(err);
}
}
字段类型
有以下的数据类型
类型 | 描述 |
---|---|
String | 字符串 |
Number | 数字 |
Boolean | 布尔值 |
Array | 数组类型,也可以用[]表示 |
Date | 日期 |
Buffer | Buffer对象,比如多媒体文件的二进制码 |
Mixed | 任意类型,需要使用mongoose.Schema.Types.Mixed指定 |
ObjectId | 对象ID,需要使用mongoose.Schema.Types.ObjectId指定 |
Decimal128 | 高精度数字,需要使用mongoose.Schema.Types.Decimal128指定 |
举例
mongoose.connection.once('open', () => {
let bookSchema = new mongoose.Schema({
name: String,
author: String,
price: Number,
isHot: Boolean,
tags: Array,
publish: Date
});
let bookModel = mongoose.model('books', bookSchema);
createBook(bookModel);
});
async function createBook(bookModel){
const data = await bookModel.create({ name: '红楼梦', author: '曹雪芹', price: 19.9, isHot: true, tags: ['古典', '社会', '情感'], publish: new Date() });
}
字段验证
有以下几种验证方法
类型 | 作用 |
---|---|
required | 表示该字段为必填字段 |
unique | 是否为唯一值(必须在新集合中实现) |
enum | 枚举类型,复赋值是必须为枚举类型中所规定的值 |
default | 字段的默认值 |
举例
mongoose.connection.once('open', () => {
let bookSchema = new mongoose.Schema({
id: {type: String, unique: true}, //unique: 是否为唯一值(必须在新集合中实现)
name: {type: String, required: true}, //required: 表示该字段为必填字段
author: {type: String, default: 佚名}, //default: 字段的默认值
source: {type: String, enum: ['中文', '外文']}, //enum: 枚举类型,复赋值是必须为枚举类型中所规定的值。
price: Number
});
let bookModel = mongoose.model('books', bookSchema);
createBook(bookModel);
});
删除文档
基于两个核心方法deleteOne和deleteMany可以分别删除单条文档和多条文档
mongoose.connection.once('open', () => {
console.log('链接数据库成功');
let bookSchema = new mongoose.Schema({
name: String,
author: String,
price: Number,
is_hot: Boolean
});
let bookModel = mongoose.model('novels', bookSchema);
//删除单条
deleteRecords(bookModel, {author: '余华'}, bookModel.deleteOne);
//删除多条
deleteRecords(bookModel, {author: '余华'}, bookModel.deleteMany);
});
async function deleteRecords(model, query, deleteFunction){
try{
const data = await deleteFunction.call(model, query);
console.log(data);
}catch(err){
console.log(err);
}
}
更新文档
基于updateOne和updateMany两个函数
mongoose.connection.once('open', () => {
console.log('链接数据库成功');
let bookSchema = new mongoose.Schema({
name: String,
author: String,
price: Number,
is_hot: Boolean
});
let bookModel = mongoose.model('novel', bookSchema);
updateRecords(bookModel, {name: '西游记'}, bookModel.updateOne, {price: 50});
});
async function updateRecords(model, query, update, newRecord){
try{
const data = await update.call(model, query, newRecord);
console.log(data);
}catch(err){
console.log(err);
}
}
读取文档
同样,基于One和Many两个函数
async function findRecords(model, query, search){
try{
const data = await search.call(model, query);
console.log(data);
}catch(err){
console.log('读取失败: ', err);
return;
}
}
调用
findRecords(bookModel, {author: '曹雪芹'}, bookModel.findOne);
findRecords(bookModel, {author: '余华'}, bookModel.findMany);
条件控制
就像if else可以通过与和或将多个条件结合使用一样,mongodb也可以;MongoDB中有以下几种条件控制
运算符
运算符 | 作用 |
---|---|
$gt | 大于 |
$lt | 小于 |
$gte | 大于等于 |
$lte | 小于等于 |
$ne | 不等于 |
举例:
findRecords(bookModel, {price: {$lt: 20}}, bookModel.findOne);
逻辑运算
运算符 | 作用 |
---|---|
$or | 或运算 |
$and | 与运算 |
举例:
findRecords(bookModel, {
$and: [
{price: {$gt: 30}},
{price: {$lt: 70}}
]
}, bookModel.findOne);
正则匹配
有两种方法
findRecords(bookModel,{name: /三/}, bookModel.findOne);
//另一种方法:
findRecords(bookModel,{name: new RegExp('三')}, bookModel.findOne);
推荐使用第二种,因为第一种无法读取变量。
个性化读取
有以下几种方法,可以显示特定的文档
方法 | 作用 |
---|---|
select | 字段筛选 |
sort | 排序 |
skip | 跳过多少条记录 |
limit | 向后显示多少条记录 |
使用方法:
//只显示返回的数据的name和author两个字段, 不显示_id字段
const data = await model.find(query).select({name: 1, author: 1, _id: 0});
//根据返回数据的price字段升序显示(-1为降序)
const data = await model.find(query).sort({price: 1}).select({name: 1, price: 1});
//只返回数据的前三条
const data = await model.find(query).sort({price: 1}).select({name: 1, price: 1}).limit(3);
//和skip组合使用
//只返回第3到第6条数据
const data = await model.find(query).sort({price: 1}).select({name: 1, price: 1}).skip(3).limit(3);
findRecords(bookModel, {
$and: [
{price: {$gt: 30}},
{price: {$lt: 70}}
]
}, bookModel.findOne);