猫鼬不会持久化嵌套数组的值/对象吗?

时间:2019-01-14 22:02:45

标签: javascript node.js json mongodb mongoose

我有一个复杂的结构,在

中定义为JSON
{
    "name": "Pricing Structure A",
    "dimensionsGroupId": 1,
    "definitions": [
        {
            "name": "PRODUCTGROUP",
            "pricingStructureDefinitionType": "categorical",
            "values": [
                "Agency Jumbo 15",
                "Agency Jumbo 30"
            ]
        },
        {
            "name": "STATE",
            "pricingStructureDefinitionType": "categorical",
            "values": [
                "AK",
                "AL",
                "AR",
                "AZ",
                "CA"
            ]
        },
        {
            "name": "PURPOSE",
            "pricingStructureDefinitionType": "categorical",
            "values": [
                "Purchase",
                "Refinance",
                "Cashout"
            ]
        },
        {
            "name": "OCC",
            "pricingStructureDefinitionType": "categorical",
            "values": [
                "OO",
                "SECH",
                "INVS",
                "OTHER"
            ]
        },
        {
            "name": "PROP",
            "pricingStructureDefinitionType": "categorical",
            "values": [
                "2UNT",
                "4UNT",
                "CND5",
                "SNGL",
                "PUD",
                "COOP",
                "MFGM",
                "Other"
            ]
        },
        {
            "name": "LTV",
            "pricingStructureDefinitionType": "binned",
            "values": [
                {
                    "binningType": "comparison",
                    "operator": "<=",
                    "value": "65.00"
                },
                {
                    "binningType": "range",
                    "start": {
                        "operator": ">=",
                        "value": "65.01"
                    },
                    "end": {
                        "operator": "<=",
                        "value": "72.50"
                    }
                },
                {
                    "binningType": "range",
                    "start": {
                        "operator": ">=",
                        "value": "72.51"
                    },
                    "end": {
                        "operator": "<=",
                        "value": "80.00"
                    }
                },
                {
                    "binningType": "range",
                    "start": {
                        "operator": ">=",
                        "value": "80.01"
                    },
                    "end": {
                        "operator": "<=",
                        "value": "87.50"
                    }
                },
                {
                    "binningType": "range",
                    "start": {
                        "operator": ">=",
                        "value": "87.51"
                    },
                    "end": {
                        "operator": "<=",
                        "value": "95.00"
                    }
                },
                {
                    "binningType": "comparison",
                    "operator": ">",
                    "value": "95.00"
                }
            ]
        }
    ]
}

我设计的架构类似于

const Schema = require("mongoose").Schema;
const model = require("mongoose").model;


const pricingStructureDefinitionValue = new Schema({}, {discriminatorKey: 'kind', _id: false});
const pricingStructureDefinitionSchema = new Schema({
    name: {type: String, required: true},
    values: {type: [pricingStructureDefinitionValue], required: true}
});
const psDefinitionArray = pricingStructureDefinitionSchema.path('values');

const categoricalDefinitionSchema = new Schema({
    name: {type: String, required: true},
    value: {type: String, required: true},
});
exports.CategoricalDefinition = psDefinitionArray.discriminator('Categorical', categoricalDefinitionSchema);


/*
const numericalDefinitionSchema = new Schema({values: {type: [Number], required: true}});
const NumericalDefinition = psDefinitionArray.discriminator('Numerical', numericalDefinitionSchema);
*/

const binDefinitionSchema = new Schema({},{discriminatorKey: 'binType', _id: false});
const binsDefinitionSchema = new Schema({
    name: {type: String, required: true},
    values: {type: [binDefinitionSchema], required: true}
});
const binArray = binsDefinitionSchema.path('values');
const comparisonBinSchema = new Schema({operator: {type: String, required: true},value: {type: 'Decimal128'}}, {_id: false});
exports.ComparisonBinDefinition = binArray.discriminator('ComparisonBin', comparisonBinSchema);




const rangeBinSchema = new Schema({
    start: {
        operator: {type: String, required: true},
        value: {type: 'Decimal128'}
    },
    end: {
        operator: {type: String, required: true},
        value: {type: 'Decimal128'}
    },
}, {_id: false});
exports.BinsDefinition = psDefinitionArray.discriminator('Binned', binsDefinitionSchema);
exports.RangeBinDefinition = binArray.discriminator('RangeBin', rangeBinSchema);

const pricingStructureSchema = new Schema({
    name: String,
    dimensionsGroupId: Number, // Schema.ObjectId
    definitions: {type: [pricingStructureDefinitionSchema], required: true}
},  {collection: 'pricing_structures'});

// const PricingStructureDefinition = model('PricingStructureDefinition', pricingStructureDefinitionSchema);


exports.PricingStructure = model('PricingStructure', pricingStructureSchema);

我创建了一个函数,可以将JSON数据插入到

的MongoDB中
const createPricingStructure = (pricingStructure = PricingStructureA) => {
    let definitions = pricingStructure.definitions.reduce((acc0, definition) => {
        console.log(JSON.stringify(definition));
        if (definition.pricingStructureDefinitionType === 'categorical') {
            return [...acc0, new CategoricalDefinition({name: definition.name, values: definition.values})];
        }
        else if(definition.pricingStructureDefinitionType === 'numerical') {
            // do nothing: here just for documentation purposes
        }
        else if(definition.pricingStructureDefinitionType === 'binned') {
            let binnedDefinitions = definition.values.reduce((acc1, bin) => {
                //console.log(JSON.stringify(bin));
                if (bin.binningType === 'comparison') {
                    return [...acc1, new ComparisonBinDefinition({operator: bin.operator, value: bin.value})];
                } else if (bin.binningType === 'range') {
                    return [...acc1, new RangeBinDefinition({
                        start: {operator: bin.start.operator, value: bin.start.value},
                        end: {operator: bin.end.operator, value: bin.end.value}
                    })];
                }
            }, []);
            console.log(JSON.stringify(binnedDefinitions));
            return [...acc0, new BinsDefinition({name: definition.name, values: binnedDefinitions})];
        }
    }, []);

    //console.log(JSON.stringify(definitions));

    // todo: pricing dimension id belongs in definition
    let ps01 = new PricingStructure({
        name: pricingStructure.name,
        dimensionsGroupId: pricingStructure.dimensionsGroupId,
        definitions: definitions
    });
    console.log(ps01);
    // console.log(`definitions size: ${definitions.length}`);

    ps01.save()
        .then(() => console.log(`saved ps01`))
        .then(() => db.close(() => console.log('connection closed')))
        .catch(err => console.error(err));

};

我以createPricingStructure();身份运行时,在console.log上看到以下内容

node src/index.js
{"name":"PRODUCTGROUP","pricingStructureDefinitionType":"categorical","values":["Agency Jumbo 15","Agency Jumbo 30"]}
{"name":"STATE","pricingStructureDefinitionType":"categorical","values":["AK","AL","AR","AZ","CA"]}
{"name":"PURPOSE","pricingStructureDefinitionType":"categorical","values":["Purchase","Refinance","Cashout"]}
{"name":"OCC","pricingStructureDefinitionType":"categorical","values":["OO","SECH","INVS","OTHER"]}
{"name":"PROP","pricingStructureDefinitionType":"categorical","values":["2UNT","4UNT","CND5","SNGL","PUD","COOP","MFGM","Other"]}
{"name":"LTV","pricingStructureDefinitionType":"binned","values":[{"binningType":"comparison","operator":"<=","value":"65.00"},{"binningType":"range","start":{"operator":">=","value":"65.01"},"end":{"operator":"<=","value":"72.50"}},{"binningType":"range","start":{"operator":">=","value":"72.51"},"end":{"operator":"<=","value":"80.00"}},{"binningType":"range","start":{"operator":">=","value":"80.01"},"end":{"operator":"<=","value":"87.50"}},{"binningType":"range","start":{"operator":">=","value":"87.51"},"end":{"operator":"<=","value":"95.00"}},{"binningType":"comparison","operator":">","value":"95.00"}]}
[{"binType":"ComparisonBin","operator":"<=","value":{"$numberDecimal":"65.00"}},{"binType":"RangeBin","start":{"operator":">=","value":{"$numberDecimal":"65.01"}},"end":{"operator":"<=","value":{"$numberDecimal":"72.50"}}},{"binType":"RangeBin","start":{"operator":">=","value":{"$numberDecimal":"72.51"}},"end":{"operator":"<=","value":{"$numberDecimal":"80.00"}}},{"binType":"RangeBin","start":{"operator":">=","value":{"$numberDecimal":"80.01"}},"end":{"operator":"<=","value":{"$numberDecimal":"87.50"}}},{"binType":"RangeBin","start":{"operator":">=","value":{"$numberDecimal":"87.51"}},"end":{"operator":"<=","value":{"$numberDecimal":"95.00"}}},{"binType":"ComparisonBin","operator":">","value":{"$numberDecimal":"95.00"}}]
{ _id: 5c3d051f66d98cf39775b8bb,
  name: 'Pricing Structure A',
  dimensionsGroupId: 1,
  definitions:
   [ { _id: 5c3d051f66d98cf39775b8b5,
       name: 'PRODUCTGROUP',
       values: [] },
     { _id: 5c3d051f66d98cf39775b8b6, name: 'STATE', values: [] },
     { _id: 5c3d051f66d98cf39775b8b7, name: 'PURPOSE', values: [] },
     { _id: 5c3d051f66d98cf39775b8b8, name: 'OCC', values: [] },
     { _id: 5c3d051f66d98cf39775b8b9, name: 'PROP', values: [] },
     { _id: 5c3d051f66d98cf39775b8ba, name: 'LTV', values: [Array] } ] }
(node:62359) DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.
saved ps01
connection closed

我们看到的,当我打印

console.log(JSON.stringify(definition));
console.log(JSON.stringify(binnedDefinitions));

我将正确的值打印为

"values":["Agency Jumbo 15","Agency Jumbo 30"]
"values":["AK","AL","AR","AZ","CA"]
"values":["Purchase","Refinance","Cashout"]
"values":["OO","SECH","INVS","OTHER"]
"values":["2UNT","4UNT","CND5","SNGL","PUD","COOP","MFGM","Other"]
"values":[{"binningType":"comparison","operator":"<=","value":"65.00"},{"binningType":"range","start":{"operator":">=","value":"65.01"},"end":{"operator":"<=","value":"72.50"}},{"binningType":"range","start":{"operator":">=","value":"72.51"},"end":{"operator":"<=","value":"80.00"}},{"binningType":"range","start":{"operator":">=","value":"80.01"},"end":{"operator":"<=","value":"87.50"}},{"binningType":"range","start":{"operator":">=","value":"87.51"},"end":{"operator":"<=","value":"95.00"}},{"binningType":"comparison","operator":">","value":"95.00"}]}
[{"binType":"ComparisonBin","operator":"<=","value":{"$numberDecimal":"65.00"}},{"binType":"RangeBin","start":{"operator":">=","value":{"$numberDecimal":"65.01"}},"end":{"operator":"<=","value":{"$numberDecimal":"72.50"}}},{"binType":"RangeBin","start":{"operator":">=","value":{"$numberDecimal":"72.51"}},"end":{"operator":"<=","value":{"$numberDecimal":"80.00"}}},{"binType":"RangeBin","start":{"operator":">=","value":{"$numberDecimal":"80.01"}},"end":{"operator":"<=","value":{"$numberDecimal":"87.50"}}},{"binType":"RangeBin","start":{"operator":">=","value":{"$numberDecimal":"87.51"}},"end":{"operator":"<=","value":{"$numberDecimal":"95.00"}}},{"binType":"ComparisonBin","operator":">","value":{"$numberDecimal":"95.00"}}]

但是,当我打印mongoose对象

console.log(ps01);

这些值不会出现在POJO

{ _id: 5c3d051f66d98cf39775b8bb,
  name: 'Pricing Structure A',
  dimensionsGroupId: 1,
  definitions:
   [ { _id: 5c3d051f66d98cf39775b8b5,
       name: 'PRODUCTGROUP',
       values: [] },
     { _id: 5c3d051f66d98cf39775b8b6, name: 'STATE', values: [] },
     { _id: 5c3d051f66d98cf39775b8b7, name: 'PURPOSE', values: [] },
     { _id: 5c3d051f66d98cf39775b8b8, name: 'OCC', values: [] },
     { _id: 5c3d051f66d98cf39775b8b9, name: 'PROP', values: [] },
     { _id: 5c3d051f66d98cf39775b8ba, name: 'LTV', values: [Array] } ] }

我想知道这里出了什么问题。
非常感谢您提供任何关于出了什么问题以及如何解决问题的指导!

谢谢

0 个答案:

没有答案