I have a Movie model in Mongoose and this has a ratings key which is an array of numbers. I am looking for some sort of method I can add to this schema that automatically calculates the average rating when I add a new rating to the array. Does anyone know how this is done?
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var schema = new Schema({
title: String,
actors: String,
director: String,
length: Number,
description: String,
genre: String,
country: String,
year: Number,
ratings: [],
averageRating: Number,
reviews: [{type: Schema.Types.ObjectId, ref: 'Review'}],
pictureUrl: String
}, { usePushEach: true });
module.exports = mongoose.model('Movie', schema);
You can define a method on the schema to do two things: add a rating to the ratings property, and then update the averageRatings property. You would then call this method instead of directly updating the ratings property.
Related
I am trying to create a mongoose schema for a json object which i will recieve from an api.
The json object has an element payMoneyid which is like this
payuMoneyId: {
"paymentId": 1112253696,
"splitIdMap": [{
"amount": 10.00,
"splitPaymentId": 1112253697,
"merchantId": 4825051,
"splitId": "splitId1"
}]
}
I have written a schema is this how it's supposed to be or it's wrong?
const formSchema = new mongoose.Schema({
payuMoneyId: {
paymentId: {
type: Number
},
splitIdMap: {
type: Mixed
}
}
})
It looks like you have just two top level fields - a number and an array of objects. Here is how to mirror that structure in a mongoose schema:
const formSchema = new mongoose.Schema({
paymentId: Number,
splitIdMap: [
new mongoose.Schema({
amount: Number,
splitPaymentId: Number,
merchantId: Number,
splitId: String
})
]
})
I am having some difficulties understanding how construct my schemas and am hoping to get some help.
In short I have three schemas Company, User and Verification. I start by creating some companies and then create and add users to the companies.
I then log in to a webpage and use a form to add rows to a table (konto, beskrivning, projekt...). Then I save the verification to a MongoDB.
First question is: Would the current schemas work for my scenario? or do I need to change something. Have I entered redundant information?
Second question: In the VerificationSchema I would like to have an incrementing value (verificationNumber) for each company that starts by 1 then increases for every added verification. The counter should be separate for each company but shared with all users in the same company.
Verification.js
const VerificationSchema = mongoose.Schema({
verificationNumber: Number,
user :{type: mongoose.Schema.Types.ObjectId, ref: 'User'},
company: {type: mongoose.Schema.Types.ObjectId, ref: 'Company'},
rows: [{
konto: Number,
beskrivning: String,
projekt: String,
debet: Number,
kredit: Number
}]
});
Company.js
const CompanySchema = mongoose.Schema({
companyName: String,
users: [{type: mongoose.Schema.Types.ObjectId, ref: 'User'}],
verifications: [{type: mongoose.Schema.Types.ObjectId, ref: 'Verification'}]
});
User.js
const UserSchema = mongoose.Schema({
userName: String,
company: {type: mongoose.Schema.Types.ObjectId, ref: 'Company'],
verifications: [{type: mongoose.Schema.Types.ObjectId, ref: 'Verification'}]
});
In a new project I started with MySQL but I want to convert it to mongodb / moongoose.
My pain here is the different relations I have in MySQL.
F.x. I have have users table
uid | firstname | lastname | email
and i housetable
hid | address | zipcode | city | ownerid
where ownerid is a user in the users table
I am a little unsure how I should design me schemas in mongoose to have an option a bit like the MySQL one.
My current user schema is like this
const userSchema = new mongoose.Schema({
firstname: String,
lastname: String,
email: String,
phone: Number,
password: String,
address: String,
zipcode: Number,
city: String,
bankname: String,
bankregno: Number,
bankaccno: Number,
userconfirmed: Boolean,
confirmtoken: String,
resettoken: String,
resettokenexpires: Date,
acceptmarketing: Boolean,
lastloggedin: Date,
disabled: Boolean
})
You can add a field for an array of houses in your userSchema to break it up and allow a one to many relation. You can do this by using subdocuments.
This could look something like this.
const houseSchema = new mongoose.Schema({
address: String,
zipcode: Number,
city: String,
})
const userSchema = new mongoose.Schema({
firstname: String,
lastname: String,
email: String,
phone: Number,
password: String,
bankname: String,
bankregno: Number,
bankaccno: Number,
userconfirmed: Boolean,
confirmtoken: String,
resettoken: String,
resettokenexpires: Date,
acceptmarketing: Boolean,
lastloggedin: Date,
disabled: Boolean,
houses: [houseSchema],
})
you can use mongoose populate, like this
const User = new mongoose.Schema({
House: { type: mongoose.Types.Schema.ObjectId, ref: "House" }
});
const House = new mongoose.Schema({
Number,
Road: String
});
(async () => {
const users = await User.find({}).populate("House");
// users = [
// {
// _id: 373890hfjklfhjkfh,
// House: {
// _id: dhkdhdlhjkld,
// Number: 378930,
// Road: fhjdlhdjkld
// }
// }
// ]
})();
If you are looking to relate both the schemas, this might help you. If you want more info, https://mongoosejs.com/docs/2.7.x/docs/populate.html
const User = mongoose.model('User', new mongoose.Schema({
firstname: {
type: String,
},
lastname: {
type: String,
},
email: {
type: String
}
}));
const Address = mongoose.model('Address', new mongoose.Schema({
owner: {
type: Schema.Types.ObjectId,
ref: 'User'
}
//rest of your address schema
}))
Here I have two schema:
var personSchema = Schema({
_id: Schema.Types.ObjectId,
name: String,
job: {
type: Schema.Types.ObjectId,
ref: 'Job',
}
});
var jobSchema = Schema({
_id: Schema.Types.ObjectId,
title: String,
});
var Job = mongoose.model('Job', jobSchema);
var Person = mongoose.model('Person', personSchema);
Suppose Job has some records:
[{
"_id" : ObjectId("5b46d41e04cfc922949dcfda"),
"Title": "Teacher"
}, ...]
When I have some person objects to insert:
[{
name: 'Peter',
job: 'Teacher'
}, ...]
Do I need to find the Job's _id and convert the job field to ObjectId type before each save? e.g.
Job.findOne({title: p.job}, (j) => {
Person.save({name: p.name, job: j._id}).exec(()=>{
// it's ok!
)}
})
Or I can use the middleware or populate function to make it easy? Thankyou!
While saving your person , you are needing a job for it.
So this is how you can proceed for the same:
Either create a new job / find an existing job.
Assign the found job's objects _id field to your new Person and save the same.
Eg.code
let person = new Person({
name : 'TszHin'
});
Job.findOne({ title : 'Abc'})
.then(function(job){
person.job = job._id;
person.save();
});
I have a relatively simple question, however, I keep getting stuck, over and over again. I think this is the fourth time I have tried to re-structure my documents to try and get the desired result.
I want to create a database in mongoose with the following structure:
A User has many groups, posts and comments. The groups, posts and comments all belong to a User. A post can belong to many groups, or none. And a comment belongs to a certain post.
Here is what I have so far:
UserSchema
var userSchema = mongoose.Schema({
local : {
email : String,
password : String,
username : String,
created: {type:Date, default: Date.now}
}
});
PostSchema
var PostSchema = new Schema({
url: String,
highlighted: String,
comment: String,
image: String,
timeStamp: String,
description: String,
title: String,
created: {type:Date, default: Date.now},
private: Boolean,
favorite: Boolean,
readlater: Boolean,
postedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
comments: [{
text: String,
postedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
}],
groups: [{
name: String,
postedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
}]
});
groupSchema
var GroupSchema = Schema({
name : String,
created: {type:Date, default: Date.now},
postedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
});
Although I may be wrong on this assumption, I think I have the post to user and comment to post relationship just the way it should be. Please correct me if I am wrong. The main problem I am having right now is with my group to post relationship. Currently, there is no relationship at all. As far as I can, it is almost as if the group belongs to the post, instead of the other way around. The only other way I can think to structure the group would be like so:
var GroupSchema = Schema({
name : String,
created: {type:Date, default: Date.now},
postedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
posts: [{
title: String,
Url: String,
comments: [{
text: String
}]
etc....
}]
});
The only problem I can see in the structure above is that the post will be required to be part of a group, which I want to be optional. So as far as I can tell, this will not work either.
If there is any advice you can provide in regards to how this should be structured, it would help me greatly.
Thank you in advance.
Your best bet is to embed your groups and comment schemas inside of your post document. For example,
var GroupSchema = Schema({
name: String,
created: { type:Date, default: Date.now },
});
var CommentSchema = Schema({
text: String,
postedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
}
});
var PostSchema = new Schema({
url: String,
...,
postedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
comments: [CommentSchema]
groups: [GroupSchema]
});
Now, if you are looking for posts with a particular group, you can build a query as follows. You can build more complicated queries than this however.
Post.elemMatch("groups", {name: {$in: ["group1", "group2"]}}).then(...)