mongoose与date混合types的字段

我正在创build一个应用程序,用户可以创build各种types的自定义字段,我想将这些字段存储在mongo中。 这些types将包括string,数字和date。 我的模式如下所示:

const MetaSchema = new mongoose.Schema({ key: String, value: {type: mongoose.Schema.Types.Mixed}, type: String, created_at: {type: Date, default: Date.now} }); 

这很好,我可以按预期存储我的数据。 问题是,当我想要存储一个实例的date,它被发送到ISO格式的服务器,有效载荷可能看起来像:

 { "key": "Contract Signed", "value": "2016-04-06T22:35:11.540Z", "type": "date" } 

任何方式我可以得到mongo /mongoose对待和存储这个像一个date,而不是一个string? 如果我设置这个键入date,那么我认为它会做的伎俩,但我必须保存任何他们可以提出自定义字段。 非常感谢!

TLDR:mongoose / mongo中的混合数据types可以根据插入的数据types(IE Date vs String)进行不同的处理。

使用mongoose鉴别器可能是这里的方式。 他们实际上使用自己的“types”(默认__t但可以覆盖)属性在存储的文件,允许mongoose实际应用一种“模型”的每个对象与自己的附加模式。

作为一个简单的例子:

 var async = require('async'), util = require('util'), mongoose = require('mongoose'), Schema = mongoose.Schema; mongoose.connect('mongodb://localhost/things'); mongoose.set("debug",true); function BaseSchema() { Schema.apply(this,arguments); this.add({ key: String, created_at: { type: Date, default: Date.now } }); } util.inherits(BaseSchema,Schema); var metaSchema = new BaseSchema(); var stringSchema = new BaseSchema({ value: String }); var numberSchema = new BaseSchema({ value: Number }); var dateSchema = new BaseSchema({ value: Date }); var MetaModel = mongoose.model('MetaModel',metaSchema), StringModel = MetaModel.discriminator('StringModel', stringSchema), NumberModel = MetaModel.discriminator('NumberModel', numberSchema), DateModel = MetaModel.discriminator('DateModel', dateSchema); async.series( [ function(callback) { MetaModel.remove({},callback); }, function(callback) { async.each( [ { "model": "StringModel", "value": "Hello" }, { "model": "NumberModel", "value": 12 }, { "model": "DateModel", "value": new Date() } ], function(item,callback) { mongoose.model(item.model).create(item,callback) }, callback ); }, function(callback) { MetaModel.find().exec(function(err,docs) { console.log(docs); callback(err); }); }, function(callback) { DateModel.findOne().exec(function(err,doc) { console.log(doc); callback(err); }); } ], function(err) { if (err) throw err; mongoose.disconnect(); } ) 

因此,由于这些基本上是“相关的”,我正在定义一个具有共同元素的“基础”模式。 那么当然每个“types”都有不同的模式。 核心“模型”的实际分配发生在这些行中:

 var MetaModel = mongoose.model('MetaModel',metaSchema), StringModel = MetaModel.discriminator('StringModel', stringSchema), NumberModel = MetaModel.discriminator('NumberModel', numberSchema), DateModel = MetaModel.discriminator('DateModel', dateSchema); 

这意味着MetaModel实际上定义了集合和“默认”模式的确定。 以下行使用该模型中的.discriminator()来定义将存储在同一个集合中的文档的其他“types”。

通过debugging输出来显示发生了什么,列表产生如下所示:

 Mongoose: metamodels.remove({}) {} Mongoose: metamodels.insert({ value: 'Hello', __t: 'StringModel', created_at: new Date("Thu, 07 Apr 2016 00:24:08 GMT"), _id: ObjectId("5705a8a8443c0f74491bdec0"), __v: 0 }) Mongoose: metamodels.insert({ value: 12, __t: 'NumberModel', created_at: new Date("Thu, 07 Apr 2016 00:24:08 GMT"), _id: ObjectId("5705a8a8443c0f74491bdec1"), __v: 0 }) Mongoose: metamodels.insert({ value: new Date("Thu, 07 Apr 2016 00:24:08 GMT"), __t: 'DateModel', created_at: new Date("Thu, 07 Apr 2016 00:24:08 GMT"), _id: ObjectId("5705a8a8443c0f74491bdec2"), __v: 0 }) Mongoose: metamodels.find({}) { fields: undefined } [ { created_at: Thu Apr 07 2016 10:24:08 GMT+1000 (AEST), __t: 'StringModel', __v: 0, value: 'Hello', _id: 5705a8a8443c0f74491bdec0 }, { created_at: Thu Apr 07 2016 10:24:08 GMT+1000 (AEST), __t: 'NumberModel', __v: 0, value: 12, _id: 5705a8a8443c0f74491bdec1 }, { created_at: Thu Apr 07 2016 10:24:08 GMT+1000 (AEST), __t: 'DateModel', __v: 0, value: Thu Apr 07 2016 10:24:08 GMT+1000 (AEST), _id: 5705a8a8443c0f74491bdec2 } ] Mongoose: metamodels.findOne({ __t: 'DateModel' }) { fields: undefined } { created_at: Thu Apr 07 2016 10:24:08 GMT+1000 (AEST), __t: 'DateModel', __v: 0, value: Thu Apr 07 2016 10:24:08 GMT+1000 (AEST), _id: 5705a8a8443c0f74491bdec2 } 

您可以看到,在分配给主模型的metamodels集合中正在创build所有内容,但是当引用每个“鉴别器模型”时,会自动创build一个包含模型名称的__t字段。 这将在稍后读取数据时使用,所以mongoose在投掷对象时知道应用哪个模型和附加模式。

自然,因为这些都有自己的模式,所以适用标准validation规则。 此外,每个types的模式附加的“实例方法”也适用于任何单独的模型。

最后, __t字段也被应用于其他任何操作(如查询或更新)中使用“鉴别器模型”之一。 如上次执行声明所示:

  DateModel.findOne().exec(function(err,doc) { console.log(doc); callback(err); }); 

而实际的通话:

 Mongoose: metamodels.findOne({ __t: 'DateModel' }) { fields: undefined } 

该属性值被自动包含在内以指示“types”并给出集合数据的“虚拟视图”,就像它只包含该特定types一样。

实际的权力实际上在于所有的对象在同一个集合中,并且mongoose在数据检索时自动分配“类types”的能力。