I'm using mongoose with the following schema for ConfigItem:
var ConfigItem = new Schema({
name: {
type: String,
required: true
},
value: {
type: String,
required: false
},
date: {
type: Date,
required: false
},
user: {
type: String,
required: false
}
});
Next, I have a function to save documents according to this schema:
function createConfigItem(_name, _value, _date, _user, callback) {
var config = new ConfigItems({
name: _name,
value: _value,
date: _date,
user: _user
});
config.save(function handleSaveConfig(err) {
if(callback){
callback(err);
}
});
}
Next, I have an unit test (mocha based) which uses that function in the following way:
createConfigItem('sftpHost', '1.1.1.1', '2018-03-15 10:06:40.713', 'user1', callback);
If I run the test under mocha (see Note1) I get the following at MongoDB:
> db.configitems.find()
{ "_id" : ObjectId("5af173b1f155a4bff29f3e35"), "name" : "sftpHost", "value" : "1.1.1.1", "date" : ISODate("2018-03-15T10:06:40.713Z"), "user" : "user1", "__v" : 0 }
which is what I expect.
However, if I run using istanbul via grunt (see Note2) to get a coverage report the same invocation to createConfigItem() creates the following documenta at DB:
> db.configitems.find()
{ "_id" : ObjectId("5af176cbcffb8cc20a1fe3c2"), "name" : "sftpHost", "value" : "1.1.1.1", "date" : ISODate("2018-03-15T09:06:40.713Z"), "user" : "user1", "__v" : 0 }
Note that in this case the date field at DB is one hour shifted with regards the _date string parameter.
I was thinking it could be related with timezones in some way, but I have ensured that my process run in UTC setting process.env.TZ = 'UTC'.
I'm a bit lost... is there any known issue regarding mongoose/grunt/istanbul with regards to dates and/or timezones? Any hint about this problem, pls?
Note1: command used:
/home/fermin/.nvm/versions/node/v6.12.3/bin/node --debug-brk=50806 --expose_debug_as=v8debug /home/fermin/src/ctxmboard/node_modules/mocha/bin/_mocha --timeout 0 --ui bdd --reporter /home/fermin/.PyCharm2018.1/config/plugins/NodeJS/js/mocha-intellij/lib/mochaIntellijReporter.js --recursive /home/fermin/src/ctxmboard/test/back/unit
Note2: command used:
/home/fermin/.nvm/versions/node/v6.12.3/bin/node --debug-brk=33002 --expose_debug_as=v8debug ./node_modules/.bin/istanbul cover --root lib/ --dir site/coverage -- /home/fermin/.nvm/versions/node/v6.12.3/lib/node_modules/grunt-cli/bin/grunt test
As suggested in one of the question comments, using strict ISO8601 format, changing
'2018-03-15 10:06:40.713'
by
'2018-03-15T10:06:40.713Z'
solved the problem
you can use moment node module https://momentjs.com/docs/
var date=moment.utc().toDate();
Related
I am pretty confused to why making the searched fields to be "index" is making the query "theoretically" slower.
I have a not very big collection of items (6240) and all of them have the following structure.
const SomeSchema = new mongoose.Schema({
data: String,
from: {
type: Number,
},
to: {
type: Number,
},
timeStamp: {
type: Date,
default: new Date()
}
})
SomeSchema.set('toJSON', {
getters: true,
transform: (doc, ret) => {
delete ret.from
delete ret.to
return sanitizeSensitiveProperties(ret)
}
})
export const Some = mongoose.model('Some', SomeSchema, 'somethings')
The strange thing came when after trying to improve the query I changed the schema to be
...
from: {
type: Number,
index: true
},
to: {
type: Number,
index: true
},
...
With this schema I run the following query
db.rolls.find({from: {$lte: 1560858984}, to: {$gte: 1560858984}}).explain("executionStats")
This are the results NOTE THAT THE 1st ONE is the one without index
"executionTimeMillis" : 6,
"totalKeysExamined" : 0,
"totalDocsExamined" : 6240,
"executionTimeMillis" : 15,
"totalKeysExamined" : 2895,
"totalDocsExamined" : 2895,
Does this result make any sense, or is just the mongo .explain() function messing around?
As you can see I am using the Mongoose Driver in the version ^5.5.13 and I am using Mongo in the version 4.0.5
It might be conceptual question about _id in mongodb.
I understand mongodb will insert a _id field automatically if you don't set key field in document.In my case, I defined a field as Object Array, I don't know why it always create a _id in each Object in Array of this field.
I do appreciate if someone could clarify it for me.
Mongoose Model Scheme definition:
module.exports = mongoose.model("Application", {
Name: String,
Description: String,
Dependency: [
{
App_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Application'
},
Priority: Number
}
]
});
This is an Update operation, request data is:
{ _id: '571953e33f33c919d03381b5',
Name: 'A Test Utility (cmd)',
Description: 'A Test Utility (cmd)'
Dependency:
[ { App_id: '571953e33f33c919d03381b6', Priority: true },
{ App_id: '571953e33f33c919d03383da', Priority: 0 } ]
}
I use this code to update it
var id = req.body._id;
Application.findOneAndUpdate({ _id: id }, req.body, function (err, app) {
if (err)
res.send(err);
res.json(app);
});
The update is successful.But the document in mongodb is:
{
"_id" : ObjectId("571953e33f33c919d03381b5"),
"Name" : "A Test Utility (cmd)",
"Description" : "A Test Utility (cmd)",
"Dependency" : [
{
"Priority" : 1,
"App_id" : ObjectId("571953e33f33c919d03381b6"),
"_id" : ObjectId("571a7f552985372426509acb")
},
{
"Priority" : 0,
"App_id" : ObjectId("571953e33f33c919d03383da"),
"_id" : ObjectId("571a7f552985372426509aca")
}
]
}
I just don't understand how come the _id in the "Dependency" Array?
Thanks.
When you use [{..}] that means inside it act as a sub schema and you know that MongoDB insert a _id field automatically if you don't set key field in document. So you need to force to insert document without _id field.
Need use {_id:false} for your Dependency array schema to insert without _id
var ApplicationSchema = new mongoose.Schema({
Name: String,
Description: String,
Dependency: [
{
App_id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Application'
},
Priority: Number,
_id: false
}
]
});
module.exports = mongoose.model("Application", ApplicationSchema);
I'm using the following schema to store some user tokens which should expire after a certain amount of time (30 minutes in this case):
var Schema = require('mongoose').Schema;
var tokenSchema = mongoose.Schema({
email: { type: String, required: true, trim: true },
token: { type: String, required: true },
created: { type: Date, expires: 60*30, default: Date.now },
}, {strict: 'throw'});
module.exports = mongoose.model('tokens', tokenSchema);
Now if I start my node.js application, I can check MongoDBfor the indexes on this collection using db.getCollection('tokens').getIndexes(). This results in:
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "node-android.resettokens"
},
{
"v" : 1,
"key" : {
"created" : 1
},
"name" : "created_1",
"ns" : "node-android.resettokens",
"expireAfterSeconds" : 1800,
"background" : true,
"safe" : null
}
]
If I now shut down my node app, change the value of expires in the token schema to something different (an hour for example), restart my node app and check the collection indexes again, I end up having the same result. I noticed this behavior after setting the TTL feature to 10 seconds for the first time to test its workings, and later finding that changing the expires value still made my documents get deleted very quickly.
So my question is: is there a way to automatically overwrite the old expires index with a new one, or do I have to delete it myself? I the latter is the case, is there a way to do this in mongoose, or do I have to execute a db.getCollection('tokens').dropIndex('created_1') via the mongo shell myself?
I'm trying to use meteor-collection2 to validate my collection.
I have a service, on server side :
Meteor.methods
UserSignUpService: (options) ->
# create user
Accounts.createUser options
That I call on client side :
Meteor.call 'UserSignUpService',
email: 'my.email#domain.com'
password: 'mypassword'
profile:
name: 'me'
And this is my schema :
# user profile
UserProfile = new SimpleSchema
name:
type: String
min: 1
max: 50
optional: false
# user
User = new SimpleSchema
emails:
type: [Object]
optional: false
"emails.$.address":
type: String
regEx: SimpleSchema.RegEx.Email
"emails.$.verified"
type: Boolean
createdAt:
type: Date
profile:
type: UserProfile
optional: false
services:
type: Object
optional: true
blackbox: true
# links to user collection
Meteor.users.attachSchema User
But, when user is created, there are not all fields in my mongo collection :
{ "_id" : "ikvBq95JBLXMCSnhT", "emails" : [ { "address" : "my.email#domain.com" } ] }
Whereas it should be :
{ "_id" : "WNkjGFhNkLpRR2Jex", "createdAt" : ISODate("2015-08-06T09:00:59.887Z"), "services" : { "password" : { "bcrypt" : "$2a$10$QvMLuI.Pv0bzzii3ZZP...fHfUlU9KiYfcsC2VHBf6q1OSPM6cfTW" }, "resume" : { "loginTokens" : [ { "when" : ISODate("2015-08-06T09:01:00.002Z"), "hashedToken" : "9KyqjRVSWm0nfIlS0sqODRmddlJ5GaG3mJ4+RMItOhk=" } ] } }, "emails" : [ { "address" : "my.email#domain.com", "verified" : false } ], "profile" : { "name" : "me" } }
Any idea on this problem ?
Many Thanks !
You're not actually setting the createdAt field value, try:
createdAt:
type: Date
autoValue: function(){
if this.isInsert return new Date()
else if this.isUpsert return { $setOnInsert: new Date };
else if this.isSet this.unset();
}
You can also omit optional: false in your schema since that's the default.
Also, and I suspect this is the bigger problem, not all user keys are returned to the client by default, only profile is normally published. For example you're expecting the services key but that doesn't normally come across. Look at the document in the mongo console and see what's there. You might need to publish a more comprehensive set of keys to the client.
I am trying to publish a node app to my Raspberrypi (the closest thing I have to a dedicated server XD ) for some of my friends to test a little web-app I wrote, but for some reason one of the queries is not working correctly on the pi when it does on my ide (cloud 9).
Here is the schema:
var campaignSchema = new Schema({
gameMaster: {
type: Schema.Types.ObjectId,
ref: "Users"
},
players: [{
type: Schema.Types.ObjectId ,
ref: "Users"
}],
name: String,
gameSystem: String,
subSystem: String
});
And here is the query:
db.Campaign.findOne({'_id' : req.params.campaign}, 'gameMaster players')
.exec(function(err, campaign){
console.log(campaign);
});
Which results in :
{
_id: 556f09195865094845a0d522,
players: []
}
But doing db.campaigns.find({}) in mongo results in:
{
"_id" : ObjectId("556f09195865094845a0d522"),
"gameMaster" : ObjectId("556d1daf4b9b697213468827"),
"gameSystem" : "Nwodv2",
"subSystem" : "Demon",
"name" : "Baltimore",
"players" : [ ],
"__v" : 0
}
I feel like I must be missing something... I don't have any idea how to resolve this though, I tried the query without a limiter on the fields, but it still omitted the gameMaster field...
Edit: at request here is the creation of the Campaign object
var campaign = new db.Campaign({
gameMaster: userid,
gameSystem: req.body.system,
subSystem: req.body.subsystem,
name: req.body.name
});
To be further confounding, this query works:
db.Campaign.findOne({'_id' : req.params.campaign},
'_id name gameSystem subSystem gameMaster players')
.populate('gameMaster', '_id displayName')
.populate('players', '_id displayName')
.exec(function(err, campaign) {
//gameMaster is valid here with the id and displayName populated...
});
https://github.com/Automattic/mongoose/issues/3020
If anyone else is having this issue. I found this bug report that can explain the cause of the problem, it is related to how you install the new mongoose 4 apparently.