资讯专栏INFORMATION COLUMN

mongoose的关联操作

张红新 / 2231人阅读

摘要:实现代码最近在做一个项目涉及到的关联查询等等,之前做的,比较多,而用的都是比较简单的存储数据,简单查询等等。

mongoose-ref

实现代码github
最近在做一个项目涉及到mongoose的关联查询等等,之前做的mysql,postgresql比较多,而mongoose用的都是比较简单的存储数据,简单查询等等。
刚开始涉及ref还是有点小晕的,查询了相关资源,也可以模模糊糊做出来,但是会有各种报错。痛下决心研究透彻点,晚上熬夜到2点终于有点小眉目了。

</>复制代码

  1. node v8.5.0

  2. mongodb

  3. 结合一个接口理解

  4. 结合promise-async-await

  5. 一般采用mvc模式,本文就直接在express里直接写了

1. 首先建立了一个mongoose-ref项目

直接使用了express -e mongoose-ref

2.在routes/index里连接mongodb数据库

</>复制代码

  1. const mongoose = require("mongoose");
  2. mongoose.connect("mongodb://localhost:27017/ref");
3.建立4个模型,用户:User,城市:City,省份:State,国家:Country

同时建立关联user->city->state->country

</>复制代码

  1. const Schema = mongoose.Schema;
  2. const ObjectId = Schema.Types.ObjectId;
  3. const UserSchema = new Schema({
  4. username: { type: String },
  5. userpwd: { type: String },
  6. userage: { type: Number },
  7. city: { type: Schema.Types.ObjectId, ref: "City" },
  8. });
  9. const CitySchema = new Schema({
  10. name: { type: String },
  11. state: { type: Schema.Types.ObjectId, ref: "State" }
  12. });
  13. const StateSchema = new Schema({
  14. name: { type: String },
  15. country: { type: Schema.Types.ObjectId, ref: "Country" }
  16. });
  17. const CountrySchema = new Schema({
  18. name: { type: String }
  19. });
  20. const User = mongoose.model("User", UserSchema);
  21. const City = mongoose.model("City", CitySchema);
  22. const State = mongoose.model("State", StateSchema);
  23. const Country = mongoose.model("Country", CountrySchema);
4.主要采用promise-async-async进行逻辑处理 首先创建一个user_getCountryList函数,如下代码

</>复制代码

  1. const user_getCountryList = async function (req, res) {
  2. console.log("/v1/ref start -->" + JSON.stringify(req.body));
  3. try {
  4. const respondData = {
  5. status: res.statusCode,
  6. data: {},
  7. error: {}
  8. };
  9. const username = req.body.username;
  10. const userpwd = req.body.userpwd;
  11. const userage = req.body.userage;
  12. const usercityname = req.body.usercityname;
  13. const userstatename = req.body.userstatename;
  14. const usercountryname = req.body.usercountryname;
  15. const userInfoCountry = await findUserCountry({ name: usercountryname }, usercountryname);//查看国家
  16. const userInfoState = await findUserState({ name: userstatename }, userstatename);//查看州
  17. const userInfoCity = await findUserCity({ name: usercityname }, usercityname);//查看城市
  18. const userInfo = await findUser({ username: username, }, username,userpwd,userage);//查看用户信息
  19. const updateInfoUser = await updateUser({ _id: userInfo },userInfoCity);//更新用户信息
  20. const updateInfoCity = await updateCity({ _id: userInfoCity }, userInfoState);//更新城市信息
  21. const updateInfoState = await updateState({ _id: userInfoState }, userInfoCountry);//更新州信息
  22. return res.json(respondData);
  23. }
  24. catch (error) {
  25. //错误处理
  26. console.log("userCity error -->" + JSON.stringify(error));
  27. respondData.error = error;
  28. return res.json(respondData);
  29. }
  30. }

首先查看传入的国家在country中有没有,加入有,返回_id,没有就创建传入的国家名,并返回_id,查看findUserCountry函数对应的逻辑

</>复制代码

  1. const findUserCountry = async function (cnd, country) {
  2. console.log("findUserCountry start --> " + JSON.stringify(cnd));
  3. return new Promise(function (resolve, reject) {
  4. Country.findOne(cnd, function (error, data) {
  5. console.log("findUserCountry findOne data --> " + JSON.stringify(data));
  6. if (error) {
  7. return reject(error);
  8. }
  9. if (data) {
  10. return resolve(data._id);
  11. } else {
  12. const userCountry = new Country({
  13. name: country
  14. });
  15. userCountry.save(function (err, data) {
  16. if (err) {
  17. console.log("userCountry.save err-->" + JSON.stringify(err));
  18. return reject(err);
  19. }
  20. console.log("userCountry-->" + JSON.stringify(data));
  21. return resolve(data._id);
  22. });
  23. }
  24. });
  25. })
  26. }

同理传入的州,城市,用户信息以同样的方式返回_id

接下来就要进行关联user->city->state->country

通俗的说就是在User表中city保存City表中所需要的_id;也就是之前返回的_id这时就可以用到,可以参考updateUser函数

</>复制代码

  1. const updateUser = async function (cnd, cityid) {
  2. console.log("updateUser start --> " + JSON.stringify(cnd));
  3. return new Promise(function (resolve, reject) {
  4. User.update(cnd, { $set: { city: cityid } }, function (error, data) {
  5. console.log("updateUser findOne data --> " + JSON.stringify(data));
  6. if (error) {
  7. return reject(error);
  8. }
  9. return resolve(data);
  10. });
  11. })
  12. }

可以使用postman模拟数据,如图:

这时就把City对应的_id写进了User表中,可以查看表,如图:


同理user->city->state->country数据都可以写进不同的表中。

5.使用populate关联查询

当传入username 时,使用populate关联查询,可以查询出这个人的所以信息

</>复制代码

  1. User.find({ username: user_name })
  2. .populate("city")
  3. .exec(function (err, docs) {
  4. City.find({ _id: docs[0].city._id })
  5. .populate("state")
  6. .exec(function (err, doc) {
  7. State.find({ _id: doc[0].state._id })
  8. .populate("country")
  9. .exec(function (err, result) {
  10. const userInfo = {};
  11. userInfo.username = docs[0].username;
  12. userInfo.userpwd = docs[0].userpwd;
  13. userInfo.userage = docs[0].userage;
  14. userInfo.usercity = doc[0].name;
  15. userInfo.userstate = result[0].name;
  16. userInfo.usercountry = result[0].country.name;
  17. respondData.data.push(userInfo);
  18. return res.json(respondData);
  19. })
  20. })
  21. });

使用postman模拟接口如下

当然这个关联查询也可以使用promise-async-await不过有时候看着这回调,层层包含还挺好看,或者这也是js的一大美感呢

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/19110.html

相关文章

  • Mongoose简要API

    摘要:是在环境下对进行便捷操作的对象模型工具因此,要使用,则必须安装环境以及数据库。使操作更简单便捷。找到记录,并且将递增,返回后的为之前的。这个属性很有用,对数字直接进行增减。,要返回的字段与的第二个参数一致。 Mongoose是在node.js环境下对mongodb进行便捷操作的对象模型工具 因此,要使用mongoose,则必须安装node.js环境以及mongodb数据库。mongoo...

    王岩威 评论0 收藏0
  • Mongoose 之 Population 使用

    摘要:使用可以实现在一个中填充其他的。表示关联注意被关联的的必须是和才有效。类型的时,格式如为表示不填充,为时表示填充。以键值对的形式表示。回调函数,接收两个参数,错误和填充完的。参考数据库的最简单实现使用之原文链接 Mongoose 是 MongoDB 的 ODM(Object Document Mapper)。 什么是ODM? 其实和ORM(Object Relational Mapp...

    timger 评论0 收藏0
  • [转]mongodb中populate方法

    摘要:使用可以实现在一个中填充其他的。表示关联注意被关联的的必须是和才有效。封装了很多查询的方法,使得对数据库的操作变得简单啦。这里分享一下方法用法。类型的时,格式如为表示不填充,为时表示填充。类型,可选,指定附加的查询条件。 Mongoose 是 MongoDB 的 ODM(Object Document Mapper)。 什么是ODM? 其实和ORM(Object Relational...

    ranwu 评论0 收藏0
  • NodeJS+Express搭建个人博客-环境搭建(一)

    摘要:本项目持续更新中,开源免费与各位爱好技术达人共勉,注现阶段仍在开发中。。。。。 NodeJS+Express+MongoDb开发的个人博客 NodeJS+Express搭建个人博客-环境搭建(一)NodeJS+Express搭建个人博客-gulp自动化构建工具使用(二)NodeJS+Express搭建个人博客-Express+Mongodb组合架构介绍(三)NodeJS+Express...

    Clect 评论0 收藏0
  • 在线考试系统(vue2 + elementui + express4 + MongoDB)

    摘要:在实际开发过程中发现,考试系统各个表集合都是需要关联,这种非关系型数据库,做起来反而麻烦了不少。数据中既有试卷的信息,也有很多题目。题目都属于该试卷,改试卷又属于当前登录系统的老师即创建试卷的老师。 这是我毕业项目,从0到1,前后台独立开发完成。功能不多,在此记录,温故而知新!项目github地址:https://github.com/FinGet/Exam ,博客地址:https:/...

    warmcheng 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<