使用 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,输出详细的内容。

输出内容如下:


{
  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)
})();

https://github.com/Innei/Back-End-Study/blob/master/express-demo/db.js

注意

  1. 立即执行函数记得一定要分号,前面加分号。