猫鼬一对多

时间:2016-02-06 19:51:43

标签: node.js mongoose routes

你能解释一下如何组织mongoose模型来创建一对多的连接吗?需要保留单独的集合。

假设我有商店和商品

// store.js

var mongoose = require('mongoose');

module.exports = mongoose.model('Store', {
    name : String,
    itemsinstore: [ String]
});

// item.js

var mongoose = require('mongoose');
module.exports = mongoose.model('Item', {
    name : String,
    storeforitem: [String]
 });

我是以正确的方式做的吗?

如何访问传递数据到arryas? 这是代码输入项目的名称。但是如何输入id到数组的id(itemsinstore)?

app.post('/api/stores', function(req, res) {
    Store.create({
        name: req.body.name,
    }, function(err, store) {
        if (err)
            res.send(err);
    });
})

4 个答案:

答案 0 :(得分:13)

您应该使用模型参考和populate()方法: http://mongoosejs.com/docs/populate.html

定义模型:

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

var storeSchema = Schema({
   name : String,
   itemsInStore: [{ type: Schema.Types.ObjectId, ref: 'Item' }]
});
var Store = mongoose.model('Store', storeSchema);

var itemSchema = Schema({
    name : String,
    storeForItem: [{ type: Schema.Types.ObjectId, ref: 'Store' }]
});
var Item = mongoose.model('Item', itemSchema);

将新商品保存到现有商店中:

var item = new Item({name: 'Foo'});
item.save(function(err) {

  store.itemsInStore.push(item);
  store.save(function(err) {
    // todo
  });
});

从商店获取商品

Store
  .find({}) // all
  .populate('itemsInStore')
  .exec(function (err, stores) {
    if (err) return handleError(err);

    // Stores with items
});

答案 1 :(得分:4)

您可以通过Virtuals使用最佳做法。

Store.js

const mongoose = require('mongoose')
const Schema = mongoose.Schema

const StoreSchema = new Schema({
    name: {
        type: String,
        required: true
    },
    createdAt: {
        type: Date,
        default: Date.now
    }
})

StoreSchema.virtual('items', {
    ref: 'Item',
    localField: '_id',
    foreignField: 'storeId',
    justOne: false // set true for one-to-one relationship
})

module.exports = mongoose.model('Store', StoreSchema)

Item.js

const mongoose = require('mongoose')
const Schema = mongoose.Schema

const ItemSchema = new Schema({
    storeId: {
        type: Schema.Types.ObjectId,
        required: true
    },
    name: {
        type: String,
        required: true
    },
    createdAt: {
        type: Date,
        default: Date.now
    }
})

module.exports = mongoose.model('Item', ItemSchema)

StoreController.js

const Store = require('Store.js')

module.exports.getStore = (req, res) => {
    const query = Store.findById(req.params.id).populate('items')

    query.exec((err, store) => {
        return res.status(200).json({ store, items: store.items })
    })
}

请记住,默认情况下,toJSON()输出中不包含虚拟机。如果要在使用依赖于JSON.stringify()的函数(例如Express'res.json() function)时显示填充虚拟机,请在架构的virtuals: true上设置toJSON选项选项。

// Set `virtuals: true` so `res.json()` works
const StoreSchema = new Schema({
    name: String
}, { toJSON: { virtuals: true } });

答案 2 :(得分:1)

好的,这就是你定义依赖的方法:

var mongoose = require('mongoose');

module.exports = mongoose.model('Todo', {
    name : String,
    itemsinstore: [{ type: Schema.Types.ObjectId, ref: 'Item' }]
});

并确保您有不同的名字:

var mongoose = require('mongoose');
module.exports = mongoose.model('Item', {
    name : String,
    storeforitem: [String]
 });

在两种情况下都要留意Item

然后你只想传递ObjectIDs数组。点击此处:http://mongoosejs.com/docs/populate.html

答案 3 :(得分:1)

试试这个:

 Store.findOne({_id:'5892b603986f7a419c1add07'})
  .exec (function(err, store){
    if(err) return res.send(err);

   var item = new Item({name: 'Foo'});
   item.save(function(err) {

   store.itemsInStore.push(item);
   store.save(function(err) {
    // todo
 });
});