首页 > 解决方案 > Mongoose(mongoDB) 链接多个模式

问题描述

我对MongoDB和比较陌生Mongoose。我很习惯 MySQL,所以习惯于调用内部连接表。我已经阅读了很多内容,您可以将两者联系起来Mongoose Schemas以达到相同的结果。当我通过 id 拨打电话以获取家务时,它会如何将这两个模式放在一起,它会返回家务然后对于assignedTo&createdBy有用户方案数据用于所述userId

家务模式

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var ChoreSchema = new Schema({
  title: {
    type: String,
    required: true
  },
  desc: {
    type: String,
    required: true
  },
  time: {
    type: Number,
    required: true
  },
  reaccurance: {
    type: [{
      type: String,
      enum: ['Daily', 'Weekly', 'Bi-Weekly', 'Monthly']
    }]
  },
  reward: {
    type: Number,
    required: true
  },
  retryDeduction: {
    type: Number,
    required: false
  },
  createdDate: {
    type: Date,
    default: Date.now
  },
  createdBy: {
    type: String,
    required: true
  },
  dueDate: {
    type: Date,
    required: true
  },
  status: {
    type: [{
      type: String,
      enum: ['new', 'pending', 'rejected', 'completed', 'pastDue']
    }],
    default: ['new']
  },
  retryCount: {
    type: Number,
    default: 0,
    required: false
  },
  rejectedReason: {
    type: String,
    required: false
  },
  familyId: {
    type: String,
    required: true
  },
  assignedTo: {
    type: String,
    required: false,
    default: ""
  }
});

let Chores = module.exports = mongoose.model('Chores', ChoreSchema);
module.exports.get = function (callback, limit) {
  Chores.find(callback).limit(limit);
};

用户模式

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var UserSchema = new Schema({
  firstName: {
    type: String,
    required: true
  },
  lastName: {
      type: String,
      required: true
  },
  role: {
    type: [{
        type: String,
        enum: ['Adult', 'Child']
      }]
  },
  birthday: {
    type: String,
    required: false
  },
  familyId: {
      type: String,
      required: true
  },
  balance: {
      type: Number,
      required: true,
      default: 0.00
  }
});

let Users = module.exports = mongoose.model('Users', UserSchema);
module.exports.get = function (callback, limit) {
  Users.find(callback).limit(limit);
};

我试图链接ChoreSchema.createdBy&ChoreScheme.assignedTo通过UserSchema._id

我如何在 Node.js 中进行调用:

exports.index = function(req, res) {
  Chore.get(function(err, chore) {
    if (err)
      res.send(err);
    res.json({
      message: 'Chore List',
      data: chore
    });
  });
};

标签: node.jsmongodbmongoose

解决方案


Mongoose 有一个更强大的替代方法,称为 populate(),它允许您引用其他集合中的文档。

https://mongoosejs.com/docs/populate.html

这是您如何链接ChoreSchema.createdByChoreScheme.assignedTo通过UserSchema._id

var mongoose = require('mongoose');
const { Schema, Types } = mongoose;

var UserSchema = new Schema({
    firstName: { type: String, required: true },
    ...
})

var ChoreSchema = new Schema({
    title: { type: String, required: true },
    ...
    //The ref option is what tells Mongoose which model to use during population
    assignedTo: { type: Types.ObjectId, ref: 'Users' },
    createdBy: { type: Types.ObjectId, ref: 'Users' },
})

let Chores = mongoose.model('Chores', ChoreSchema);
let Users = mongoose.model('Users', UserSchema);

然后在您的express路线处理程序中,您可以assignedTocreatedBy这样填充

router.get('/chores/:id', function (req, res) {
    const choreId = req.params.id;
    Chores.find({ _id: choreId })
        .populate('createdBy') // populate createdBy
        .populate('assignedTo') // populate assignedTo
        .exec(function (err, chore) {
            if(err) {
                return res.send(err)
            }
            res.json({ message: 'Chore List', data: chore });
        });
})

推荐阅读