概念
Node.js 的优雅 mongodb 对象建模
Mongoose 提供了一种直接的、基于模式的解决方案来对应用程序数据进行建模。它包括开箱即用的内置类型转换、验证、查询构建、业务逻辑挂钩等
安装
npm i mongoose
具体例子
E:\Nextjs\mongoose-use-demo\app\api[crud]\route.ts
连接数据库
E:\Nextjs\mongoose-use-demo\lib\db.ts
import mongoose from 'mongoose';
export const connectDB = async () => {
try {
await mongoose.connect(process.env.MONGO_URI as string)
console.log('db is connect with', mongoose.connection.host);
} catch (error) {
console.log("Error connecting to MongoDB: ", error);
}
}
E:\Nextjs\mongoose-use-demo.env.local
MONGO_URI=mongodb://127.0.0.1:27017/mongoose-use-demo
定义架构(表中字段)
Mongoose 中的一切都始于架构。每个架构映射到一个 MongoDB 集合并定义该集合 中 文档的形状
import mongoose from 'mongoose';
const { Schema } = mongoose;
const blogSchema = new Schema({
title: String, // String is shorthand for {type: String}
author: String,
body: String,
comments: [{ body: String, date: Date }],
date: { type: Date, default: Date.now },
hidden: Boolean,
meta: {
votes: Number,
favs: Number
}
});
https://mongoosejs.com/docs/guide.html
简单例子
const User = new Schema({
name: String,
age: Number,
sex: String
});
代码将在每次测试之前尝试创建一个名为“ModelName”的新模型
用户架构
src/models/User.js
import mongoose from "mongoose";
const { Schema } = mongoose;
const userSchema = new Schema(
{
name: {
type: String,
unique: true,
required: true,
},
email: {
type: String,
unique: true,
required: true,
},
password: {
type: String,
required: true,
},
},
{ timestamps: true }
);
//If the User collection does not exist create a new one.
export default mongoose.models.User || mongoose.model("User", userSchema);
文章架构
src/models/Post.js
import mongoose from "mongoose";
const { Schema } = mongoose;
const postSchema = new Schema(
{
title: {
type: String,
required: true,
},
desc: {
type: String,
required: true,
},
img: {
type: String,
required: true,
},
content: {
type: String,
required: true,
},
username: {
type: String,
required: true,
},
},
{ timestamps: true }
);
//If the Post collection does not exist create a new one.
export default mongoose.models.Post || mongoose.model("Post", postSchema);
自动建立时间戳
const User = new Schema({
name: String,
age: Number,
sex: String
},{
timestamps:true
});
https://mongoosejs.com/docs/timestamps.html
const userSchema = new Schema({ name: String }, { timestamps: true });
const User = mongoose.model('User', userSchema);
let doc = await User.create({ name: 'test' });
console.log(doc.createdAt); // 2022-02-26T16:37:48.244Z
console.log(doc.updatedAt); // 2022-02-26T16:37:48.244Z
如果集合中有文档,再添加新的字段
新添加的文档有新字段,旧的没有
创建模型(表)
将架构转换成可使用
的模型,模型是从架构定义编译而来的奇特构造函数,模型的实例称为文档,模型负责从底层 MongoDB 数据库创建和读取文档
当您在架构上调用 mongoose.model() 时,Mongoose 会为您编译一个模型
mongoose.model(modelName, schema)
用法
const UserModel = mongoose.model('User', User);
但是实际使用中我们更倾向使用下面的用法
export const userModal = mongoose.models.users || mongoose.model('users',Schema)
如果存在users模型,就不需要再创建,重复创建同一名字的模型会报错
创建文档(记录)
模型的实例称为文档。创建它们并将其保存到数据库很容易
const Tank = mongoose.model('Tank', yourSchema);
const small = new Tank({ size: 'small' });
await small.save();
// or
await Tank.create({ size: 'small' });
// or, for inserting large batches of documents
await Tank.insertMany([{ size: 'small' }]);
例子
const user = await userModal.create({
name: username,
age: parseInt(age),
sex
})
查询文档
集合中的文档
找多个文档时
find()
可以传三个参数
filter
«Object|ObjectId» 过滤[projection]
«Object|String|Array[String]» 返回特定存在的字段[options]
«Object» 限制数量、跳过查询等等
https://mongoosejs.com/docs/api/query.html#Query.prototype.select()
https://mongoosejs.com/docs/api/query.html#Query.prototype.setOptions()
查找集合中所有文档
const users = await userModal.find({});
查找某个特定属性的文档
const users = await userModal.find({name:'aaa'},"name");
筛选某个属性小于某个值的文档
const users = await userModal.find({ age: { $lte: 7 } })
or
const users = await userModal.find({}).where('age').lt(7)
模糊查询(正则)
name字段有aa值的文档
const users = await userModal.find({ name: /aa/i },"name sex")
只显示name和sex字段
find()第二个参数可以传字符串
// include a and b, exclude other fields
query.select('a b');
// Equivalent syntaxes:
query.select(['a', 'b']);
query.select({ a: 1, b: 1 });
跳过
const users = await userModal.find({},null,{skip:5});
筛选出符合多个条件的文档
User.find({ age: { $gte: 21, $lte: 65 } });
只找一个文档时
通过id找文档
这个id是文档唯一标识_id
const users = await userModal.findById('656c6f5ece8ea04466736424')
在多个匹配文档中选第一个findOne()
const users = await userModal.findOne({name:'aaa'},"name");
更改文档
const users = await userModal.updateOne({name:'aa'},{name:'aa1',sex:'woman'});
根据id更改
await Topic.findByIdAndUpdate(id, { title, description });
删除文档
const users = await userModal.deleteOne({name:'aaa'});
根据id删除
await Topic.findByIdAndDelete(id);
偶尔分享web开发知识
小破站
blog