2

I have many fields in my documents of type date intervals, such as this

{
    publishDate:
    {
       start: {type: Date, required: true},
       end: {type: Date, required: true}
    }
}

To reduce duplication of the code and make it easier to maintain, how to create custom Mongoose type, for instance DateInterval, containing two fields:

  1. start
  2. end

and containing validator that makes sure both fields are filled out, and start is before end?

Dario
  • 3,905
  • 2
  • 13
  • 27
Ismar Slomic
  • 5,315
  • 6
  • 44
  • 63

3 Answers3

3

You can reuse schemas in mongoose.

var DateIntervalSchema = new Schema({
   start: {type: Date, required: true},
   end: {type: Date, required: true}
});

var SomeSchema = new Schema({
   publishDate: [DateIntervalSchema],
   // ... etc
});

You can also reference documents from other collections.

var SomeSchema = new Schema({
   publishDate: {type: Schema.ObjectId, ref: 'DateInterval'}
});    

//using populate
SomeModel.findOne({ someField: "value" })
   .populate('publishDate') // <--
   .exec(function (err, doc) {
      if (err) ...

   })
Josh C.
  • 4,303
  • 5
  • 30
  • 51
  • Doesn't the first example declare an **array** DateIntervals, meaning there could be also 0, 2 or lots of intervals in the document? – Udo G Sep 09 '16 at 16:38
1

You'll want to develop a custom schema type. There are a number of plugins that do this already, one of which, for long numbers, can be found here: https://github.com/aheckmann/mongoose-long/blob/master/lib/index.js . This is a good basic example to follow.

For your purposes, then, you can create a DateInterval custom schema, casting it as type Date, and then use a validator to check start and end - http://mongoosejs.com/docs/api.html#schematype_SchemaType-validate.

glortho
  • 13,120
  • 8
  • 49
  • 45
  • 1
    This looks interesting, but all custom schema type examples I have seen so far is having one single value, while I'm having two: _start_ and _end_. Not seeing right away how to modify mongoose-long example to support two fields and how to be able to set these two fields when using the model (for instance event.publishDate.start and event.publishDate.end). Any input, @glortho? – Ismar Slomic Jun 30 '14 at 18:00
0

Since >=4.4 you can implement your custom schema type.

Documentation is not very clear, but you can follow this example.

You have to:

  • define your DateInterval custom object with toBSON() / toJSON() and toObject() prototype methods

  • define the DateIntervalType inherited from mongoose.SchemaType for handle the mongoose integration, and casting to DateInterval.

In this way you can achieve full control on memory (Mongoose model) and mongodb (raw's bson) data representation.

Community
  • 1
  • 1
Dario
  • 3,905
  • 2
  • 13
  • 27