MongoDB default values are not saved, instead re-calculated at runtime - node.js

I'm building a simple REST app on the Yeoman Express MVC generator with MongoDB.
This is my MongoDB/Mongoose model (updated with complete update.js model):
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var UpdateSchema = new Schema({
title: String,
text: String,
authors: String,
url: String,
imageUrl: String,
dateCreated: { type: Date, default: Date.now },
reloadNeeded: { type: Boolean, default: true }
});
mongoose.model('Update', UpdateSchema);
This is what the data looks like in the Mongo client:
> db.updates.find();
{ "_id" : ObjectId("5476453f8920d05ecdef4eec"), "title" : "Hello World", "text" : "yoda yoda" }
{ "_id" : ObjectId("547653748920d05ecdef4eed"), "title" : "Hihi", "text" : "mookie" }
And this is the JSON output from my Express app:
[
{"_id":"5476453f8920d05ecdef4eec","title":"Hello World","text":"yoda yoda","reloadNeeded":true,"dateCreated":"2014-11-27T10:50:10.078Z"},
{"_id":"547653748920d05ecdef4eed","title":"Hihi","text":"mookie","reloadNeeded":true,"dateCreated":"2014-11-27T10:50:10.078Z"}
]
So, dateCreated and reloadNeeded are set at runtime - but I'd rather want them set (and persisted) when I create the documents. What's going on?
Update: seems like values are persisted if I create from Mongoose rather than the MongoDB shell.

Do you use mongoose for data model? If it so, default values will be created on document construction http://mongoosejs.com/docs/2.7.x/docs/defaults.html
Anyway I assume the reason is in defaults

Related

mongoose: $match isn't find documents

I created a schema Machine:
import mongoose from 'mongoose';
import moment from 'moment';
const Schema = mongoose.Schema;
const MachineSchema = new Schema({
device_name: {
type: String,
unique: true
},
state: String,
count_pings: {
type: Number,
default: 1
},
created_at: {
type : Number,
default: moment().format('x')
},
last_work_time_at: {
type : Number,
default: moment().format('x')
}
});
export default mongoose.model('Machine', MachineSchema);
I send the query using aggregate framework to MongoDB:
require('dotenv').config();
import mongoose from 'mongoose';
import Machine from './models/machine';
const fiveMinutesAgo = moment().subtract(process.env.INTERVAL_TIME_IN_MINUTES, 'minutes').format('x');
Machine.aggregate([
{$match: {last_work_time_at: {$lt: fiveMinutesAgo}}},
{$project: {_id: 1, device_name: 1, last_work_time_at: 1}}
])
.then(results => {
console.log(results);
})
I want to get all documents for which value of last_work_time_at is less than value of fiveMinutesAgo.
I use mongoose of version 4.11.7.
Here, for example the document stored in collection:
{
"_id" : ObjectId("59a6c8a5811e812935f3c6d4"),
"device_name" : "cg0011",
"state" : "unworking",
"last_work_time_at" : 1504102558069.0,
"created_at" : 1504102558069.0,
"count_pings" : 15844,
"__v" : 0
}
I have same else 10 documents and for which absolutely every value of field last_work_time_at is less than value of `fiveMinutesAgo, but result of query is empty array.
I don't understand why don't get any documents by query. I'm thinking that somewhere made a little error and that is why isn't search it still.
Please, help me. Thanks in advance.

mongodb mongoose nodejs express4 why insert a _id in Object Array field automatically?

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);

How to set up Mongoose schema to store an array of objects in MongoDB?

I currently have an array that contains multiple objects nested inside of it.
Here is the format...
[ { id: 1, title: 'Squats', video: 'https://www.youtube.com/watch?v=aPYCiuiB4PA' }, { id: 2, title: 'Push-Ups',video: 'https://www.youtube.com/watch?v=aPYCiuiB4PA' }]
I am attempting to .save() it in my Schedule model that looks like this...
var ScheduleSchema = new mongoose.Schema({
schedule: [Object]
})
When I run the following code in the Schedule controller on the server side, the .save() function gives me a 'success' message (that I programmed it to give), but when I look inside my MongoDB database, it saves incorrectly with nothing inside of the schedule array.
This is what the saved information looks like in the database....
{ "_id" : ObjectId("56c28a0d4c92bec03408c077"), "schedule" : [ ], "__v" : 0 }
I have a feeling my model is set up wrong.
Model schemas I have tried...
1) schedule: []
2) schedule: [Schema.Types.Mixed]
Just in case this is helpful, here is my .save() function when I try to save said data from the schedule controller...
var new_schedule = new Schedule(req.body.info);
new_schedule.save(function(err){
if(err){
console.log('err');
}else{
console.log('worked');
}
})
I'd suggest setting up your schema like this:
var ScheduleSchema = new mongoose.Schema({
schedule: [mongoose.Schema.Types.Mixed]
});
That would be the proper way to set it up. Another way to do it would be to define the object in-line, like this:
var ScheduleSchema = new mongoose.Schema({
schedule: [{
id: { type: Number, default: 1 },
title: { type: String, default: '', trim: true },
video: { type: String, default: '', trim: true }
}]
});
Also, it may not be a problem on the server side code. Before you create the new Schedule with req.body.info, you might want to put in a line like this:
console.log(JSON.stringify(req.body, null, 2));
This will print out the req.body object in a readable format so that you can make sure the client app is sending the information you think you are getting.
Make a model of inline objects in schema.
Use this :
var model = mongoose.model("CollectionName",SchemaName);
model.insertMany(arrayOfSchedules , function(err,docs){});

mongodb date insert like using mongoose

I am inserting bulk records in mongodb. I am using the native DB drivers to do this, as the performance is much higher. At other points in my application, i am using mongoose. The problem I am having is that mongoose translates the date into a different format whereas mongodb native just inserts it as the number of seconds since 1970. So later queries in mongoose based off that date do not work.
Here's my mongoose schema:
var MySchema = new Schema({
name : { type: String, required: true },
updatedAt : Date
});
And my mongo db mass insert:
var newRec = {
name : entry.Name,
updatedAt : Date.now
};
newRecords.push(newRec);
MySchema.collection.insert(newRecords, function(err, newRecs) {
res.json(newRecs.ops);
});
This produces in the DB:
{
"_id": {
"$oid": "562818ecf24d540f0053a38d"
},
"name": "Cool Record",
"updatedAt": 12312423512
}
Whereas if it was run through Mongoose it would produce:
{
"_id": {
"$oid": "561fd90285b5e73f5626f74e"
},
"name": "Cool Record",
"updatedAt": {
"$date": "2015-10-20T20:01:17.553Z"
}
}
If going through mongoose, queries like this work well:
MySchemda.find({ updatedAt : { $gt: lastSynced }}).exec();
But do not work otherwise.
Date.now is a number representing milliseconds since 1970. While it conceptually represents a date, it isn't actually a Date:
var x = Date.now;
typeof x;
// "number"
You need to switch your schema to be:
var MySchema = new Schema({
name : { type: String, required: true },
updatedAt : Number
});
alternately, you can use:
var newRec = {
name: entry.Name,
updatedAt: new Date()
}
and keep your schema as it is.
You may use it like this:
Define the date type and the default value, then create a variable which can be defined as your schema use year : new Date this would help a lot to set the date.
var songSchema = new mongoose.Schema({
name : String,
year : {type : Date, default : Date.now},
singer : String,
});
var song = mongoose.model("song", songSchema);
var xyz= new song({
name : "abcd",
year :new Date, // to set the date first set new Date
singer : "aabbccdd",
});
You can use setDate , setMonth, setYear method to solve the issues.There are more methods defined under the object year .You can out further at the documentation of mongoose.
xyz.save(function(err, songs){
if(err)
winston.log("Something is wrong"+ " "+ err);
else {
songs.year.setDate(03);
songs.year.setMonth(03);
songs.year.setYear(2015);
winston.log(songs);
}
});

How to add data to array in Mongoose Schema

Assuming the following schema, I am trying to save some GeoJSON data with Mongoose
var simpleSchema = new Schema({
properties:{
name:String,
surname:String
},
location : {
type : String,
coordinates : [ Number , Number ]
}
});
This is how I try to save the document
var a = new simple({properties:{name:"a", surname:"b"}, location:{type:"Point", coordinates:[1, 0]}}).save(function(err){...});
However, what I am getting in the database is
ObjectId("542da9ab0882b41855ac3be0"), "properties" : { "name" : "a", "surname" : "b" }, "__v" : 0 }
It looks like the whole location tag and data are missing. Is this a wrong way to define a schema or a wrong way of saving the document?
When using a field named type in an embedded object, you need to use an object to define its type or Mongoose thinks you're defining the type of object itself.
So change your schema definition to:
var simpleSchema = new Schema({
properties:{
name:String,
surname:String
},
location : {
type : { type: String },
coordinates : [ Number , Number ]
}
});

Resources