Automattic / mongoose

MongoDB object modeling designed to work in an asynchronous environment.
https://mongoosejs.com
MIT License
27.01k stars 3.85k forks source link

Mongoose "instance" value representing the Date type is undefined in Schema object #1938

Closed ssmereka closed 7 years ago

ssmereka commented 10 years ago

I am programmatically creating CRUD methods for mongoose schemas when I noticed something strange. It seems for Date types in mongoose that the "instance" value in the exported schema object is undefined where others are correctly defined (such as Number, ObjectID, etc.).

I am not sure if this is a bug, or if maybe you could offer an explanation as to why mongoose works this way.

In the example below, you can see that dateCreated is of Date type, but the "instance" property value is undefined.

var MySchema = new Schema({
    key:               { type: String, unique: true, required: true },
    usedCount:    { type: Number, default: 0 },
    maxUse:        { type: Number, default: 1},
    dateCreated:  { type: Date, default: Date.now }
  });
console.log(MySchema.paths);

Console Output:

{ key:
   { enumValues: [],
     regExp: null,
     path: 'key',
     instance: 'String',
     validators: [ [Object] ],
     setters: [],
     getters: [],
     options: { type: [Function: String], unique: true, required: true },
     _index: { unique: true },
     isRequired: true },
  usedCount:
   { path: 'usedCount',
     instance: 'Number',
     validators: [],
     setters: [],
     getters: [],
     options: { type: [Function: Number], default: 0 },
     _index: null,
     defaultValue: 0 },
  maxUse:
   { path: 'maxUse',
     instance: 'Number',
     validators: [],
     setters: [],
     getters: [],
     options: { type: [Function: Number], default: 1 },
     _index: null,
     defaultValue: 1 },
  dateCreated:
   { path: 'dateCreated',
     instance: undefined,
     validators: [],
     setters: [],
     getters: [],
     options: { type: [Function: Date], default: [Function: now] },
     _index: null,
     defaultValue: [Function: now] },
  _id:
   { path: '_id',
     instance: 'ObjectID',
     validators: [],
     setters: [ [Function: resetId] ],
     getters: [],
     options: { type: [Function: ObjectId], auto: true },
     _index: null,
     defaultValue: [Function: defaultId] } }
_id: ObjectID
name: String
queryName: String
index: Number
_id: ObjectID
ssmereka commented 10 years ago

bump ^ ^

mikeclymer commented 10 years ago

It looks like Date type instance values are not supported as an external interface: https://github.com/LearnBoost/mongoose/issues/1430

I need something similar as well. I use the instance type values to build dynamic document filter sets with the aggregation framework.

formula1 commented 10 years ago

I'm Running into the Same problem with Booleans. I don't think he wants mongoose to be used for automation.

vkarpov15 commented 10 years ago

Worth thinking about. Right now, the instance field is not intended to be used to determine what type the path should be in external code. Why not just use options.type instead?

bestconsultant commented 10 years ago

In my case options.type is not defined either for Date or Boolean. My workaround is to add a type2 property which will appear under options.type2 type: Date, type2: 'Date'

charlie-s commented 9 years ago

Why don't the Boolean and Date schema definitions include their type the same way Number, ObjectId, and String do?

For example, ./lib/schema/string.js:

function SchemaString (key, options) {
  this.enumValues = [];
  this.regExp = null;
  SchemaType.call(this, key, options, 'String');
};

and ./lib/schema/boolean.js:

function SchemaBoolean (path, options) {
  SchemaType.call(this, path, options);
};

Is it harmful to call the following?

function SchemaBoolean (path, options) {
  SchemaType.call(this, path, options, 'Boolean');
};
formula1 commented 9 years ago

I was looking into this deeply before, I ended up creating my own types to avoid conflicts

Doing a simple search for "instance" it doesn't even appear to be used internally.

This is the first issue I remember seeing that basically told me they weren't particularly interested in fixing it. For what its worth, you can always make a pull request (the changes are really simple) and see what feedback/lackof you get. That being said, I don't want to say its a lost cause, but I will definitely say this has been an issue for nearly 2 years : /

charlie-s commented 9 years ago

Well, it's really good to hear someone else say the same thing. I'll gladly fork and issue a PR.

On Fri, Feb 27, 2015, 6:43 PM Sam Tobia notifications@github.com wrote:

I was looking into this deeply before, I ended up creating my own types https://github.com/formula1/node-mongoose-jumpstart/blob/master/SchemaTypes/Boolean/schema.js to avoid conflicts

Doing a simple search for "instance" https://github.com/LearnBoost/mongoose/search?l=javascript&p=1&q=.instance&utf8=%E2%9C%93 it doesn't even appear to be used internally.

This is the first issue https://github.com/LearnBoost/mongoose/issues/1430 I remember seeing that basically told me they weren't particularly interested in fixing it. For what its worth, you can always make a pull request (the changes are really simple) and see what feedback/lackof you get. That being said, I don't want to say its a lost cause, but I will definitely say this has been an issue for nearly 2 years : /

— Reply to this email directly or view it on GitHub https://github.com/LearnBoost/mongoose/issues/1938#issuecomment-76499157 .

formula1 commented 9 years ago

!!! It got merged! :O

ssmereka commented 9 years ago

huzzah!!! :+1:

gregksurveillus commented 7 years ago

And it's still "broken" in the 5.03 release as of today.

fraserprice commented 7 years ago

Yeah I'm getting Date as undefined type if I try to create schema with Date object

vkarpov15 commented 7 years ago

@gregksurveillus @fraserprice this particular issue should be fixed. Please open up a separate github issue with detailed code samples.

gregksurveillus commented 7 years ago

Given the original detailed code that opened the issue, this is still happening in the release version I cited:

Console Output:

... dateCreated: { path: 'dateCreated', instance: undefined,

Did you mean was fixed in a prior release? If so, has it broken again. Or did you mean it should be fixed in the future? Or did it get fixed and released?

vkarpov15 commented 7 years ago

Issue looks fixed to me @gregksurveillus , here's the output of running the original code for me with mongoose 4.11.1. Not sure what "release 5.03" means to you, mongoose doesn't have such a release.

$ node gh-1938.js 
Schema {
  obj: 
   { key: { type: [Function: String], unique: true, required: true },
     usedCount: { type: [Function: Number], default: 0 },
     maxUse: { type: [Function: Number], default: 1 },
     dateCreated: { type: [Function: Date], default: [Function: now] } },
  paths: 
   { key: 
      SchemaString {
        enumValues: [],
        regExp: null,
        path: 'key',
        instance: 'String',
        validators: [Object],
        setters: [],
        getters: [],
        options: [Object],
        _index: [Object],
        isRequired: true,
        requiredValidator: [Function],
        originalRequiredValue: true },
     usedCount: 
      SchemaNumber {
        path: 'usedCount',
        instance: 'Number',
        validators: [],
        setters: [],
        getters: [],
        options: [Object],
        _index: null,
        defaultValue: 0 },
     maxUse: 
      SchemaNumber {
        path: 'maxUse',
        instance: 'Number',
        validators: [],
        setters: [],
        getters: [],
        options: [Object],
        _index: null,
        defaultValue: 1 },
     dateCreated: 
      SchemaDate {
        path: 'dateCreated',
        instance: 'Date',
        validators: [],
        setters: [],
        getters: [],
        options: [Object],
        _index: null,
        defaultValue: [Function: now] },
     _id: 
      ObjectId {
        path: '_id',
        instance: 'ObjectID',
        validators: [],
        setters: [Object],
        getters: [],
        options: [Object],
        _index: null,
        defaultValue: [Function: defaultId] } },
  aliases: {},
  subpaths: {},
  virtuals: { id: VirtualType { path: 'id', getters: [Object], setters: [], options: {} } },
  singleNestedPaths: {},
  nested: {},
  inherits: {},
  callQueue: [ [ 'pre', [Object] ] ],
  _indexes: [],
  methods: {},
  statics: {},
  tree: 
   { key: { required: true, unique: true, type: [Function: String] },
     usedCount: { default: 0, type: [Function: Number] },
     maxUse: { default: 1, type: [Function: Number] },
     dateCreated: { default: [Function: now], type: [Function: Date] },
     _id: { type: [Object], auto: true },
     id: VirtualType { path: 'id', getters: [Object], setters: [], options: {} } },
  query: {},
  childSchemas: [],
  plugins: [],
  s: 
   { hooks: Kareem { _pres: {}, _posts: {} },
     kareemHooks: 
      { count: true,
        find: true,
        findOne: true,
        findOneAndUpdate: true,
        findOneAndRemove: true,
        insertMany: true,
        update: true,
        updateMany: true,
        updateOne: true } },
  options: 
   { retainKeyOrder: false,
     typeKey: 'type',
     id: true,
     noVirtualId: false,
     _id: true,
     noId: false,
     validateBeforeSave: true,
     read: null,
     shardKey: null,
     autoIndex: null,
     minimize: true,
     discriminatorKey: '__t',
     versionKey: '__v',
     capped: false,
     bufferCommands: true,
     strict: true } }
$ 
gregksurveillus commented 7 years ago

$ npm mongoose -v

5.0.4

charlie-s commented 7 years ago

@gregksurveillus That's giving you the version of npm.

gregksurveillus commented 7 years ago

Sorry about that. New to the infrastructure and pulled an old version of mongoose in one of my projects.

vkarpov15 commented 7 years ago

No worries. For future reference use npm list | grep mongoose to find the mongoose version