猫鼬关系设计

时间:2016-11-17 08:27:23

标签: node.js mongodb relationships mongoose-schema mongoose-populate

我最近开始在Node.js应用程序中使用Mongoose和Express.js,我对设计模式的正确方法有疑问。

我有几个有一些关系的模式,即Location模式有一个Objects数组(在这个上下文中它不是JS对象),而Object模式有它的Location属性。我已经了解到Mongoose中的关系是通过使用填充来解决的,但是当我实现这种方法时,我注意到我必须键入许多重复的代码,即每当我想创建一个新的Object时,我还必须更新Location& #39;对象数组,然后将位置分配给对象的属性。在一个单独的查询中手动组装所有具有locationId属性的对象并不等于我想从数据库获取的位置会不会更加轻而易举?

我还考虑过将对象存储在Location文档中的数组中(作为子文档),但我决定我希望能够与Locations分开处理对象(创建,删除,更新)(无需查询位置)所以这种方法并不适合我的需求。但是在我的情况下人口也有其缺点,所以我认为最好只是通过该位置的id在单独的查询中手动收集特定位置的对象。

我希望听到一些专业或高级用户对设计Mo​​ngoose模式的意见,以便我和其他人在以后维护和扩展我们的应用程序时不会遇到麻烦。

以下是我目前的模式:

var locationSchema = new mongoose.Schema({
    title: String,
    objects: [{ type: String, ref: 'object' }]
});

var objectSchema = new mongoose.Schema({
    title: String,
    location: { type: String, ref: 'location' }
});

1 个答案:

答案 0 :(得分:1)

查看此示例

分贝/ schemas.js:

const Schema = mongoose.Schema;

const ObjectSchema = {
    title: Schema.Types.String
}

const LocationSchema = new Schema({
    title: Schema.Types.String,
    objects: [{type: Schema.Types.ObjectId, ref: 'Object'}]
})

module.exports = {
  Object: ObjectSchema,
  Location: LocationSchema
};




分贝/ model.js:

const 
 mongoose = require('mongoose'),
 schemas = require('./schemas');

module.exports = model => mongoose.model(model, schemas[model+'Schema']);




用法:

const 
  model = require('./db/model'),
  LocationModel = model('Location');

LocationModel
  .findOne({_id: 'some id here'})
  .populate('objects')
  .exec((err, LocationInstance) => {
    console.log(LocationInstance.title, ' objects:', LocationInstance.objects); 
  });




当您创建对象并想要与位置相关时:

const 
  model = require('./db/model'),
  ObjectModel = model('Object'),
  LocationModel = model('Location');

let 
  ObjectInstance = new ObjectModel({title: 'Something'});
  ObjectInstance.save((err, result) => {
    LocationModel
      .findByIdAndUpdate(
        'some id here', 
        {$push: {objects: ObjectInstance._id}},
        (err) => {
          console.log('Object:', ObjectInstance.title, ' added to location');
        });
  });




更新对象数据:

  const 
    model = require('./db/model'),
    ObjectModel = model('Object');

  let id = 'id of object';

  ObjectModel
    .findByIdAndUpdate(
      id, 
      {title: 'Something #2'},
      (err) => {
        console.log('Object title updated');
      });




按对象查找位置:

  const 
    model = require('./db/model'),
    LocationModel = model('Object');

  let id = 'id of object';

  LocationModel
    .findOne({objects: id})
    .populate('objects')
    .exec((err, LocationInstance) => {
      console.log('Location objects:', LocationInstance.objects);
    });

没有什么特别的findOne({objects: id})会在对象数组中搜索具有id关系的位置文档


欢迎任何其他问题(: