How save data in mongodb without specific req.bodys - javascript

I discover that i don't need this:
var body = req.body;
var event = new EventModel({
dateO: dateObject,
date: body.date,
name: body.name,
type: body.type,
meetingPoint: body.meetingPoint,
info: body.info,
men: body.men,
women: body.women,
description: body.description
});
event.save.......
I can use just:
var event = new EventModel(req.body);
event.save.......
If all the inputs 'name' have the same name of my attr's in my database, mongoose can save just passing the req.body.
My question is:
I have in my HTML form the following inputs with the names:
date;
name;
type;
meetingPoint;
info;
men;
women;
description;
If i do just the var event = new EventModel(req.body), will save this values, but there is a problem:
I have this dateO, and I need to deal with it in my backend.
I tried to do the following:
req.body.dateO = what i want. But i cant use the req.body in the controller.
How can i use just the:
var event = new EventModel(req.body); and still pass the dateO??
UPDATE:
I have the following schema:
var EventSchema = new mongoose.Schema({
dateO: {
type: Date
},
date: String,
name: String,
meetingPoint: String,
info: String,
men: String,
women: String,
description: String,
});
And i have this html inputs:
<input name="date"/>
<input name="name"/>
<input name="type"/>
<input name="meetingpoint"/>
<input name="info"/>
<input name="men"/>
<input name="women"/>
<input name="description"/>
It would be perfect if it were not for one problem:
I want use the input date field in the 'DD/MM/YYYY' format, and i cant, cause mongoose just except 'MM/DD/YYYY', so i am dealing with this problems like this:
var body = req.body;
var dateObject = new Date(body['date'].replace( /(\d{2})\/(\d{2})\/(\d{4})/, "$2/$1/$3"));
Them i can send like the way that i want to my database. My question is:
How can i send the dataO using the new event model in just one line:
var event = new EventModel(req.body);

You should be using a Date object here directly and not setting other field. It would be much more simple for your client code to just use a timestamp value in the form, which can even be obtained from it's own Date object handler.
That' the clean good advice, but you just need some extra smarts in your schema to obtain a date object from the "string" in the Date field:
var EventSchema = new mongoose.Schema({
dateO: {
type: Date
},
date: String,
name: String,
meetingPoint: String,
info: String,
men: String,
women: String,
description: String,
});
eventSchema.pre('save',function(next) {
this.dateO =
new Date(this.date.replace( /(\d{2})\/(\d{2})\/(\d{4})/, "$2/$1/$3"));
next();
});
So just move your logic into a "pre save" hook, and the field will be created based on the current data before the .save() is processed.

Related

How to store a datetime using mongoose?

I made this to store data of some meetings but I want the field "date" to store values as datetime like in a mysql base. How can I do this?
const mongoose= require('mongoose')
const Schema= mongoose.Schema
const Meets= mongoose.model('Meet', new Schema({
id1: String,
id2: String,
date: Date
}))
module.exports= Users
Your schema should be in below format for store Meeting time in DateTime format.
const mongoose= require('mongoose')
const Schema= mongoose.Schema
const Meets= mongoose.model('Meet', new Schema({
// First meeting recipient
id1: { type: Schema.Types.ObjectId, required: true },
// Second meeting recipient
id2: { type: Schema.Types.ObjectId, required: true },
// Date and Time of meeting
date: { type: Date, required: true }
}))
module.exports= Meets
Now, When you will make an entry in Meets collection, You will find below format of date key in your mongo database:
ISODate("2017-04-02T15:30:00Z")
This represents that the above is in ISO Date format which gives time into UTC format. To convert it in your local time format, you can do below step:
new Date(meet.date).toLocaleString();
Also, you can set property {timestamps:true} in your schema, which will additionally add createdAt and updatedAt field in your collection, which will automatically get updated at creation and each update.
Thanks
What kind of date format you want to store? If you want it to be stored in milliseconds, then you can set timestamps option to true like this:
const Meets= mongoose.model('Meet', new Schema({
id1: {String},
id2: {String},
}, {timestamps:true}))

How do I check the value of a field in a mongo database

I am creating a Node app that would need to check the fields of a collection and return what the data type is. For example if the field is "First Name" the data type would be "String". How would I get started creating a back end application that does this?
In case you are using mongoose , then Each field or nested field is addressed by path.
var myschema = new Schema({
...
name: {
first:{type: String, required: true,},
last :{type: String, required: true,},
...
});
here name.first and name.last are paths.
Now to know the type of name.last there is an Schema API, called path().So.
var pathmeta = myschema.path(name.last);
console.log(" datatype = "+pathmeta.instance);
console.log(" whole pathmeta structure is "+JSON.stringify(pathmetas));
should print this..
datatype = String
whole pathmeta structure is
{"enumValues":[],"regExp":null,"path":"text","instance":"String","validators":[],"setters":[],"getters":[],"options":{},"_index":null}

Make or simulate a join in mongodb

I would like to simulate a join query in mongodb using mongoose. There is no nested data, just two Schemas, where the OrderSchema:_id, is referencing DetailSchema: orderId
It's a bad solution to get all the orders and then query each of their details one by one. I have tried using populate in mongoose, but that only worked if i changed the scheme, and that is not a possibility. I simply cannot think of a clean way to do it!
var OrderSchema = mongoose.Schema({
_id: Number,
customerId: String,
employeeId: Number,
orderDate: String,
requiredDate: String,
shippedDate: String,
shipVia: String,
freight: Number,
shipName:
});
exports.OrderModel = mongoose.model('orders', OrderSchema);
var DetailsSchema = mongoose.Schema({
orderId: Number,
productId:
quantity: Number,
discount: Number
});
Just change your DetailSchema definition to define orderId as a reference to Order:
var DetailsSchema = mongoose.Schema({
orderId: {type: Number, ref: 'Order'},
productId: Number,
quantity: Number,
discount: Number
});
This doesn't require any change to the actual data in your existing doc, the ref is just metadata that Mongoose uses to know which model's _id the field contains a reference to.
With that in place, you can use populate to pull in the order details as:
Details.find().populate('orderId').exec(function(err, details) { ... });

Automatic createdAt and updatedAt fields in Meteor

In my collection I'd like to have automatically generated createdAt and updatedAt fields that would contain the date of when the object was inserted / updated for the last time - kind of like it's happening in Ruby on Rails. Currently I'm doing this with an observer similar to this one:
MyCollection.find({}).observeChanges({
changed: function(id, changes) {
MyCollection.update(id, ...);
},
});
Is there a better / more efficient / more straightforward way?
I use Collection2. It supports autoValue in the schema, a function that computes the forced value of a field. As these two fields are used in all collections, you can save them to a variable:
#SchemaHelpers =
createdAt:
type: Date
autoValue: ->
if #isInsert
return new Date
if #isUpsert
return $setOnInsert: new Date
if #isUpdate
#unset()
return
updatedAt:
type: Date
autoValue: ->
return new Date
And then in the collection:
Schema = {}
Posts = new Meteor.Collection("posts")
Schema.Posts = new SimpleSchema
createdAt: SchemaHelpers.createdAt
updatedAt: SchemaHelpers.updatedAt
title:
type: String
max: 30
body:
type: String
max: 3000
Posts.attachSchema(Schema.Posts)
This solution makes updatedAt always present and its value will be very close to createdAt when it is just inserted (not necessarily the same). If you need updatedAt not to be set when inserting, you can use something like the example in the Collection2 readme:
updatedAt: {
type: Date,
autoValue: function() {
if (this.isUpdate) {
return new Date();
}
},
denyInsert: true,
optional: true
},
but this does not handle upserts. I don't know any good solution that handles upserts correctly and leaves the field empty at inserts.
I like https://github.com/matb33/meteor-collection-hooks
collection.before.insert (userId, doc) ->
doc.createdAt = new Date().valueOf #toISOString()

Mongoose.js: force always populate

Is there a way to instruct model to populate ALWAYS a certain field?
Something like, to have "field" populated in any find query:
{field: Schema.ObjectId, ref: 'Ref', populate: true}
?
With Mongoose 4.0, you can use Query Hooks in order to autopopulate whatever you want.
Below example is from introduction document by Valeri Karpov.
Definition of Schemas:
var personSchema = new mongoose.Schema({
name: String
});
var bandSchema = new mongoose.Schema({
name: String,
lead: { type: mongoose.Schema.Types.ObjectId, ref: 'person' }
});
var Person = mongoose.model('person', personSchema, 'people');
var Band = mongoose.model('band', bandSchema, 'bands');
var axl = new Person({ name: 'Axl Rose' });
var gnr = new Band({ name: "Guns N' Roses", lead: axl._id });
Query Hook to autopopulate:
var autoPopulateLead = function(next) {
this.populate('lead');
next();
};
bandSchema.
pre('findOne', autoPopulateLead).
pre('find', autoPopulateLead);
var Band = mongoose.model('band', bandSchema, 'bands');
this plugin is a solution to your question:
https://www.npmjs.com/package/mongoose-autopopulate
I use query hook to autopopulate, but it not works with create() and save() for modified fields.
This is my code:
var autoPopulate = function(next) {
this.populate('updated_by','name').populate('created_by','name');
next();
};
ProjectSchema.pre('findOne', autoPopulate);
ProjectSchema.pre('find', autoPopulate);
If I update Project only created_by is populated
If I create new Project both created_by and updated_by are not populated.
find and findOne works with no problems.
What should I do to always populate both: created_by and updated_by?

Categories