Mongoose鉴别器不适用于嵌入式集合

时间:2015-04-12 17:15:39

标签: node.js mongodb mongoose

这是我的基本架构:

var mongoose = require("mongoose");
var utils= require("util");
var Schema = mongoose.Schema;

function BaseSchema(){
    Schema.apply(this, arguments);

    this.add({
        name: String,
        description: String,


    })

};

utils.inherits(BaseSchema, Schema);

module.exports = BaseSchema;

这是我的嵌入式BaseSchema模型:

    var StepSchema = require('./step')
    var schema = mongoose.Schema({
        name: String,
        description: String,
        steps: [new StepSchema()]

    });

    schema.plugin(timestamps);

    var Funnel = mongoose.model('Funnel', schema);

    module.exports = Funnel;

现在每当我保存这样的记录时:

var funnel = new Funnel(req.body);
funnel.steps.push(new ActionStep({name: "test",actionType: "Notification"}));
funnel.save(function(err, b){
            if (err) {
                res.status(500).end();
            };

            res.json({funnel:b});

        });

不会保存discrimator键。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

我认为你应该在Funnel模型上使用鉴别器然后保存它将包括有区别的字段,就像创建Funner模型之后,我们可以定义鉴别器:

var StepSchema = require('./step')
var schema = mongoose.Schema({
    name: String,
    description: String,
    steps: [new StepSchema()]

});

schema.plugin(timestamps);

var bossSchema = new BaseSchema({ name: String, actionType: String }); 

var Funnel = mongoose.model('Funnel', schema);

var Boss = Funnel.discriminator('Boss', bossSchema)

现在,在保存记录的同时:

var boss = new Boss({name: "test", actionType: "Notification" });
boss.save(function(err,boss) {

     if (err) {
            res.status(500).end();
        };

  });
var funnel = new Funnel(req.body);
funnel.steps.push(boss);
funnel.save(function(err, b){
        if (err) {
            res.status(500).end();
        };

        res.json({funnel:b});

    });

Which will produce output like this:

Boss:
{
"__v": 0,
"name": "test",
"actionType": "Notification",
"__t": "Boss",
"_id": "54a1951210a7a1b60316111a"
}

Funnel:
{
"steps":[
"__v": 0,
"name": "test",
"actionType": "Notification",
"__t": "Boss",
"_id": "54a1951210a7a1b60316111a"
]
}

正如您所看到的,Boss有一个不同的结构,特别是_t属性以及不同对象的其他定义属性。但实际上存储在相同的“步骤”集合中,可以这样查询。

因此,请检查您的集合中是否存在与架构定义不同的现有文档,并考虑所示方法以表示对象的不同“类型”的“多态”关联。

答案 1 :(得分:0)

这是我的基本架构的一个示例:

 var mongoose = require("mongoose");
    var Schema = mongoose.Schema;
    var Business = require('../models/business');
    var BusinessProductCategory = require('../models/businessProductCategory');
    var MasterProduct = require('../models/masterProduct');

    var common = require('../middlewares/common');

    var nameMinLength = [3, 'The value of path `{PATH}` (`{VALUE}`) is shorter than the minimum allowed length ({MINLENGTH}).'];

    var options = {discriminatorKey: 'kind'};

    var businessProductSchema = mongoose.Schema({
        business: {type: Schema.Types.ObjectId, ref: 'Business'},
        productPrices: [{
            value: {type: Number, required: true},
            currency: {type: String, required: true},
            description: {type: String, required: true},
            createdAt: {type: Date, default: Date.now, required: true},
            updatedAt: {type: Date, default: Date.now, required: true}
        }],
        is_show_in_store: {type: Boolean, default: true, required: true},
        record_status: {type: String, enum: ['active', 'archived'], required: true, default: 'active'},
    }, options);

    businessProductSchema.post('save', common.handlerMongoErrors);
    businessProductSchema.post('update', common.handlerMongoErrors);

    var BusinessProduct = mongoose.model("BusinessProduct", businessProductSchema);

    var ManagedProduct = BusinessProduct.discriminator('ManagedProduct', new mongoose.Schema({
        master_product: {type: Schema.Types.ObjectId, ref: 'MasterProduct'},
    }), options);

    var LocalProduct = BusinessProduct.discriminator('LocalProduct', new mongoose.Schema({
        name: {type: String, required: true, minlength: nameMinLength},
        description: {type: String},
        primary_category: {type: Schema.Types.ObjectId, ref: 'BusinessProductCategory'},
        brand: {type: String, required: true},
        created_at: {type: Date, required: true},
        updated_at: {type: Date, required: true},
    }, options));

    module.exports = {BusinessProduct: BusinessProduct, ManagedProduct: ManagedProduct, LocalProduct: LocalProduct};