Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

default date remains the same as the date of the process startup if indexed #3675

Closed
joviol opened this issue Dec 15, 2015 · 8 comments
Closed
Labels
can't reproduce Mongoose devs have been unable to reproduce this issue. Close after 14 days of inactivity.

Comments

@joviol
Copy link

joviol commented Dec 15, 2015

I have observed a very strange behavior while using the following schema:

var saleSchema = new Schema ({
  ...
  date: {type: Date, 'default': Date.now, index: true}
 ...
})

When I create a new document with the aforementioned schema the date that is placed in the database is always the same and corresponds to the start time of the current process.
It feels like when indexed the now function is called when the schema is created and reused for every newly created documents.
Is this something that makes sense?
I solved for now by removing the indexing on that field, but that means that research by date will be fairly slow.

Thank You

@vkarpov15
Copy link
Collaborator

Hmm the below script gives me the correct result:

var assert = require('assert');
var mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/gh3675');
mongoose.set('debug', true);

var Schema = mongoose.Schema;

var saleSchema = new Schema ({
  date: {type: Date, 'default': Date.now, index: true}
});

var Sale = mongoose.model('Sale', saleSchema);

console.log(new Sale().date);

setTimeout(function() {
  console.log(new Sale().date);
  process.exit(0);
}, 2000);
$ node gh-3675.js 
Tue Dec 15 2015 09:57:23 GMT-0500 (EST)
Mongoose: sales.ensureIndex({ date: 1 }) { background: true }  
Tue Dec 15 2015 09:57:25 GMT-0500 (EST)

Can you see if you can modify the provided script to reproduce your issue?

@vkarpov15 vkarpov15 added the can't reproduce Mongoose devs have been unable to reproduce this issue. Close after 14 days of inactivity. label Dec 15, 2015
@vkarpov15 vkarpov15 modified the milestones: 4.3.2, 4.3.3 Dec 15, 2015
@vkarpov15 vkarpov15 modified the milestones: 4.3.5, 4.3.4 Dec 23, 2015
@vkarpov15
Copy link
Collaborator

Issue's gone stale, closing.

@vkarpov15 vkarpov15 removed this from the 4.3.5 milestone Jan 4, 2016
@brycelund
Copy link

I ran into this problem. Be sure you're not using Date.now(), as that assigns a default value to the model instead of Date.now which causes the function to run each time.

@srlowe
Copy link

srlowe commented Sep 21, 2018

I believe I'm also getting this for { type: Date, default: new Date() }. Using Mongoose version 4.13.12

Did anyone figure out what might have been causing this? Thanks.

@lineus
Copy link
Collaborator

lineus commented Sep 21, 2018

@bgSosh

TL;DR

Instead of

{ type: Date, default: new Date() }

try

{ type: Date, default: () => { return new Date() } }

With this change, each time you create a new doc, the default function will be called and a new Date will be returned as the default.

As @brycelund pointed out, the schemaType default property can hold either a value or a function. If a value is set as the default, ie, the return of new Date() or Date.now(), then each subsequent doc created from this schema will receive the exact same default value that was set when the Schema was compiled into a model.

Alternatively, if the default is a function, like Date.now ( no parens means we're setting the default property to the function Date.now itself ) or () => { return 'xyz' }, then each doc will receive a new value from calling that function as it's default.

Here's an example that explicitly tests for the difference in behavior between passing a value and passing a function as the value for a schemaType default property:

In the following example, note that both the value passed into the schemaSame.d.default and the value returned from the schemaDiff.d.default function are computed in exactly the same way.

3675.js

#!/usr/bin/env node
'use strict';
const assert = require('assert');
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost:27017/test', { useMongoClient: true });
const conn = mongoose.connection;
const Schema = mongoose.Schema;

const schemaSame = new Schema({
  d: {
    type: Date,
    default: Date.now() + Math.floor(Math.random() * 500000) // value
  }
});

const schemaDiff = new Schema({
  d: {
    type: Date,
    default: () => { return Date.now() + Math.floor(Math.random() * 500000);} // function
  }
});

const Same = mongoose.model('same', schemaSame);
const Diff = mongoose.model('diff', schemaDiff);

const sames = [new Same(), new Same(), new Same()];
const diffs = [new Diff(), new Diff(), new Diff()];

async function run() {
  assert.strictEqual(mongoose.version, '4.13.12');
  await conn.dropDatabase();
  await Same.create(sames);
  await Diff.create(diffs);

  // docs created from schemaSame all get the exact
  // same default Date.
  let s = await Same.find();
  let s1 = s[0].d.toString();
  let s2 = s[1].d.toString();
  let s3 = s[2].d.toString();
  assert.strictEqual(s1, s2);
  assert.strictEqual(s2, s3);

  // docs created from schemaDiff all get
  // different default Dates.
  let d = await Diff.find();
  let d1 = d[0].d.toString();
  let d2 = d[1].d.toString();
  let d3 = d[2].d.toString();
  assert.notStrictEqual(d1, d2);
  assert.notStrictEqual(d2, d3);

  console.log('All Assertions Pass.');
  return conn.close();
}

run();

Output:

issues: ./3675.js
All Assertions Pass.
issues:

@srlowe
Copy link

srlowe commented Sep 21, 2018

@lineus Oh that's great info, thanks so much for taking the time!

@Lucas-Geitner
Copy link

Thanks @lineus !

@prakhartkg
Copy link

{default: Date.now()} will be called when the model has loaded means when service started.
change this to {default: Date.now} so when a new model will be created Date.now function will be called. and it will create new date.

@Automattic Automattic locked as resolved and limited conversation to collaborators Sep 29, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
can't reproduce Mongoose devs have been unable to reproduce this issue. Close after 14 days of inactivity.
Projects
None yet
Development

No branches or pull requests

7 participants