Mongoose documents states that we can create a custom _id value instead of using default Object(...) id .
var User = new mongoose.Schema({
_id : { type: String, unique: true },
name: {type: String},
device_os: {type: String},
added_on: {type: Date, default: Date.now}
});
User.pre('save', function(done) {
_id = new Date().toString(8);
console.log("inside save pre",_id);
done();
});
This is not creating new document with custom _id field. Anything i m doing wrong over here ?
Related
This question was asked several times, but despite that, I wasn't able to solve my problem. In my mongoose collection, I store 30 users with the following mongoose schema. I want to implement a newsletter on my site, therefore I want to add the new field:
newsletter: {
type: Boolean,
default: true
},
My question is: How can I add newsletter false/true to every user?
I found that, but it didn't work.
User.updateMany({}, [{ $set: { newsletter: false }}])
My Schema:
const mongoose = require('mongoose');
const UserSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true },
password: { type: String, required: true },
date: { type: Date, default: Date.now },
token: { type: String, required: true }
});
const User = mongoose.model('User', UserSchema);
module.exports = User;
Adding to the schema "newsletter" does solve the problem for new users, but doesn't add the field to the already existing ones.
As the question states, I'm failing to get this update operation to work.
My scenario:
I have an Event, a Ticket and a TicketPurchase. The Event and TicketPurchase have Ticket arrays as properties.
What I need to achieve:
Update the validated property of a particular Ticket in the ticket array of the TicketPurchase from true/false.
Decrement the total_quantity property of the same ticket from 1. in the master Event table.(all tickets in a TicketPurchase are copies of tickets in the master Event table)
Almost all my experience as a programmer has been spent working with MySQL, so I am still very much a beginner in the NoSQL world.
What I have tried:
Checked the docs
Spent some time on S/O and this proved to be the most relevant answer, but I can't get this solution to work.
Interchanged my usages of id and _id, putting operators like $set in and out of ' ' marks, and all other similar configurations, nothing will give.
ticket.js
const TicketSchema = new Schema({
type : {type: String},
total_quantity : {type: Number},
price : {type: String},
limit_per_order: {type: Number},
start_date: {type: Date},
end_date: {type: Date},
description: {type: String},
validated: {type: String, default: 'false'}
});
event.js
const EventSchema = new Schema({
title: {type: String},
location: {type: String},
start_date: {type: Date},
start_time: {type: String},
end_date: {type: Date},
end_time: {type: String},
description: {type: String},
organizer_name: {type: String},
organizer_about: {type: String},
cover_picture: {type: String},
tickets: [{type: Schema.Types.ObjectId, ref: 'Ticket'}],
access_code: {type: String, default: shortid.generate}
});
ticketPurchase.js
const TicketPurchaseSchema = new Schema({
user: {type: Schema.Types.ObjectId, ref: 'User'},
event: {type: Schema.Types.ObjectId, ref: 'Event'},
tickets: [{type: Schema.Types.ObjectId, ref: 'Ticket'}],
time_stamp: {type: Date}
});
update.js
for(var x of ticketPurchase.tickets){
//console.log(x);
if(x.id === ticket_id && x.validated === 'false'){
console.log('ticket not validated. Update');
TicketPurchase.update(
{_id: ticket_purchase_id, 'tickets._id': ticket_id},
{'$set':{
'tickets.$.validated': 'true'
}},
function (err){
console.log('updated validated');
if(err){console.log(err);}
}
);
Event
.update({_id: event_id, "tickets._id": x.id},
{$inc : {"tickets.$.total_quantity" : -1}});
console.log('updated ticket.total_qty');
payload['success'] = 'true';
}else if(x.id === ticket_id && x.validated === 'true'){
console.log('ticket validated');
payload['success'] = 'false';
payload['message'] = 'Ticket already validated.';
}
}
At first, here is a short example of how you could avoid cycles and do everything with only mongoose methods:
TicketPurchase.findById(purchaseId, (err, ticketPurchase) => {
Ticket.update({ _id: { $in: ticketPurchase.tickets }, _id: ticket_id, validated: 'false' },
{ $set: { validated: 'true' }, $inc: { total_quantity: -1 } },
(err, outcome) => {
console.log(`The number of validated tickets for the Purchase #${purchaseId} is ${outcome.nModified}`);
});
});
Here it does everything in the same operation: finds the ticket which belongs to the purchase and isn't validated yet, thereafter it sets the validated property to 'true' and decrements the quantity. Finally, you'll get the total number of modified records.
In your example I can't see that you've populated your tickets in the purchaseTicket. To iterate through ticket objects in the manner you wrote, you'd be compelled to populate it for their parent entity since the property ticketPurchase.tickets contains only references. The expression would look like: TicketPurchase.findById(purchaseId).populate('tickets').then(purchase => { ... })
Where purchase has the property tickets filled up with its ticket objects instead of merely id objects.
Adding to that, you seem not to have to update tickets in the Event schema since you can do it directly in the Ticket schema (just like I did in my example overhead) since all the references eventually point out to their objects in the schema.
I want to push an nested element Mongoose.
Check the schema:
const Messages = new mongoose.Schema({
/*[user]*/
author: {
type: Schema.Types.ObjectId,
ref: 'Users'
},
/*[room]*/
room: {
type: Schema.Types.ObjectId,
ref: 'Rooms'
},
message_body: String,
message_status:{type: Boolean, default: false},
created_at: { type: Date, default: Date.now }
});
I want to create a Message with room and Author insert, how to use that?
Imagine you have an 'author' object and a 'room' object. These are going to be the parents. Your message object would be like this:
var newMessage = new Message({author: authore._id, room: room._id, message_body: messageBody ....});
newMessage.save()
.then(() => {
/*** do more things **/
});
Then you will be able to use 'populate' option to make Mongoose refilling author and room fields with the whole objects.
I'm trying to use discountSchema as a type. But I'm getting this error:
throw new TypeError('Undefined type at `' + path +
^
TypeError: Undefined type at `discount`
but if I transform to type array:
discount: {
type: [discountSchema],
default:{}
}
it works.
How can I use complex type in mongoose as this?
Am I using this model in a wrong way? How can I model this object like this?
var discountSchema = new Schema({
type: {type: String,default:'' },
quantity: {type: Number,default:0 },
value: {type: Number,default:0 }
});
var objectEncomendaPropertiesSchema = {
recheios:{
type:[String],
default: [],
select: true
},
availableEncomenda: {
type: Boolean,
default:false
},
discount: {
type: discountSchema,
default:{}
}
};
You cant't set embedded documents stored as single property in mongoose, they are always stored in arrays.
The closest thing to this behaviour is setting your property to an ObjectId with a ref and using the populate method to fetch it.
Take a look here to see how this approach works.
Check out embedded documents docs.
There is an open issue on GitHub requesting the behaviour you want.
are you trying to create two Schemas then wire them up?
var discountSchema = new Schema({
type: {type: String,default:'' },
quantity: {type: Number,default:0 },
value: {type: Number,default:0 }
});
mongoose.model('Discount', discountSchema);
var objectEncomendaPropertiesSchema = new Schema({
recheios:{
type: String,
default: '',
select: true
},
availableEncomenda: {
type: Boolean,
default:false
},
discount: {
type: Schema.Types.ObjectId,
ref: 'Discount'
}
})
mongoose.model('objectEncomendaProperties', objectEncomendaPropertiesSchema);
I reference the discount in the second schema to reference to the first schema by the ObjectId
It will fetch the properties in the Discount model as a discount property in the second Schema.
Take a look at the following schema:
var userSchema = new mongoose.Schema({
fullName: {
type: String,
required: true,
index: true
},
activationId: {
type: mongoose.Schema.ObjectId
}
});
userSchema.path('activationId').default(function() {
return new mongoose.Schema.ObjectId.fromString('actvt');
});
It is about the "activationId", I want to generate an ID (unique code, objectID prefered since that is already built-in Mongoose) once a user gets created, so if I have the following code:
var newUser = new User({
fullName: 'Rick Richards'
});
newUser.save(function(error, data){
console.log(data.activationId); // Should give the activationId
});
But this solution gives me the following error:
TypeError: undefined is not a function
You can do this by defining a default property for the activationId field that's the ObjectId constructor function:
var userSchema = new mongoose.Schema({
fullName: {
type: String,
required: true,
index: true
},
activationId: {
type: mongoose.Schema.ObjectId
default: mongoose.Types.ObjectId
}
});