使用 Mongoose 基于 MongoDB 建模并设置关联
使用 Mongoose 简单的建立一个博客数据库以及模型之间的关联。
初始化项目
mkdir -p mongoose-model
cd mongoose-model
npm init -y
npm i mongoose
touch index.js
建立模型
首先建立对数据库的连接。
const mongoose = require("mongoose");
mongoose.connect("mongodb://127.0.0.1:27017/moogose-model-demo", {
useNewUrlParser: true
});
建立 Post 模型。
const Post = mongoose.model(
"Post", // 模型名称
new mongoose.Schema({
title: String,
categories: [ // 分类与分类模型相关联
{
type: mongoose.SchemaTypes.ObjectId, // 关联分类模型中的唯一 _id
ref: "Category" // 关联的模型名称
}
]
})
);
建立 Category 模型。
const Category = mongoose.model(
"Category",
new mongoose.Schema({
name: String
})
);
插入几条数据。
Post.insertMany([{
title: "第 1 条",
},{
title: "第 2 条",
}])
Category.insertMany([{
name: "vuejs"
},{
name: "nodejs"
}])
建立关联
之所以要进行关联,是因为为了后期维护和可操作性。
对 Post 加入分类字段与之关联。
;(async function() {
const cate1 = await Category.findOne({
name: "vuejs"
});
const cate2 = await Category.findOne({
name: "nodejs"
});
const post1 = await Post.findOne({
title: "第1篇帖子"
});
const post2 = await Post.findOne({
title: "第2篇帖子"
});
post1.categories = [cate1, cate2]; // 直接赋值即可
post2.categories = [cate1];
await post1.save(); // 保存修改
await post2.save();
const posts = await Post.find().populate("categories");
// console.log(posts[0], posts[1]);
})();
首先把 Post 和 Category 找出来,然后把分类字段改掉,最后别忘了保存。
populate()可以跟踪关联的_id
,输出详细的内容。
输出内容如下: ```js
{ categories: [ { _id: 5d30626d7fc5f875b856e403, name: 'vuejs', v: 0 }, { _id: 5d30626d7fc5f875b856e402, name: 'nodejs', v: 0 } ], _id: 5d3061a43f97af74e8e62f38, title: '第1篇帖子', v: 22 } { categories: [ { _id: 5d30626d7fc5f875b856e403, name: 'vuejs', v: 0 } ], _id: 5d3061bb5617a5750523af66, title: '第2篇帖子', __v: 22 } ```
使用分类模型反查文章
因为分类模型中不存在对 Post 的记录所以查询的时候要建立虚拟字段。首先要修改 Category 的模型。
CategorySchema.virtual("posts", {
// 定义一个虚拟字段
ref: "Post", // 关联的模型
localField: "_id", // 内建 ☞Category 的键
foreignField: "categories", // 外键 ☞ Post 的键
justOne: false // 结果只有一条还是多条
});
const Category = mongoose.model("Category", CategorySchema);
修改之后直接就可以查询到了。
;(async function() {
const cates = await Category.find()
.populate("posts")
// .lean();
console.log(cates[0].posts, cates[1].posts);
// console.log(JSON.stringify(cates))
// console.log(cates)
})();
注意
- 立即执行函数记得一定要分号,前面加分号。