I'm new in Mongoose and I want to create a 'complex' sorting. So I have the following schemas:
var UserSchema = new Schema({
firstName: String,
lastName: String,
...
skills : [{ type: Schema.Types.ObjectId, ref: 'Skill' }]
});
var ProjectSchema = new Schema({
name: String,
description: String,
...
skills : [{ type: Schema.Types.ObjectId, ref: 'Skill' }]
});
var SkillSchema = new Schema({
name: String
});
So given those schemas what I need is to sort by the matching percentage between the user skills and the project skills, so basically I want to show first the projects that are more related to the user. Is that possible by using just mongoose? If so I guess I will need to create a sorting function that I can pass to the query or something.
Thank you!
Related
I'm fairly new to programming, and am now at the stage where I am working on projects before starting to apply for jobs. I’m working on an express project and wanted some advice on my schema design, just in case I’m going about things in a horrible way.
The premise of the project is a desk booking app. A business administrator can create an account to register a company and add multiple offices if needed. Employees can also register as employees of a company using the unique company code and passcode, and then book desks in different offices.
This is the schema I have designed, I’ve modelled the data in this way as I want to be able to access the data in different ways e.g. an employee viewing all bookings they have made, as well as an employer viewing all bookings made in an office.
Any feedback would be much appreciated! Thanks in advance.
NB: When building the project I will have each schema in a different file, and I know I haven't required all the dependencies I will need. The purpose of this question is purely on best practices for mongoose schema design.
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const CompanySchema = new Schema({
companyName: String,
companyLogo: String,
uniqueCompanyCode: String,
companyPasscode: String,
companyAdmin: [
{
type: Schema.Types.ObjectId,
ref: "User"
}
],
offices: [
{
type: Schema.Types.ObjectId,
ref: 'Office'
}
],
})
const UserSchema = new Schema({
username: {
type: String,
required: true,
unique: true
},
email: {
type: String,
required: true,
unique: true
},
bookings: [
{
type: Schema.Types.ObjectId,
ref: 'Booking'
}
]
})
UserSchema.plugin(passportLocalMongoose);
const OfficeSchema = new Schema({
officeAddress:{
streetAddress: String,
town: String,
county: String,
postcode: String
},
floorPlan: String,
desks: [
{
deskNumber: Number,
bookings:{
type: Schema.Types.ObjectId,
ref: 'Booking'
}
}
]
})
const bookingSchema = new Schema({
bookedFrom: Date,
bookedTo: Date,
bookedBy: {
type: Schema.Types.ObjectId,
ref: "User"
}
})
If you’re using the architecture of Node.js, MongoDB with mongoose, you’ll create these schemas at the beginning of every project so it’s best to get familiar with them.
This is how we create a schema in mongoose.
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
let productSchema = new Schema({
name: {
type:String,
required:true
},
price: {
type:Number,
required:true
},
isAvailable: {
type:Boolean
}
});
const productModel = mongoose.model("product", productSchema);
module.exports = productModel;
The first parameter of the mongoose.model is the name of the collection that will contain the documents. The second parameter is the schema. Now, we need is to export productModel so they can be used elsewhere.
const productModel = mongoose.model("product", productSchema);
This productModel is ready to be imported and used to create data following our schema in the product collection. This is a common development pattern when using Node.js and MongoDB. An ODM-like mongoose makes managing your data more intuitive.
I come from an SQL background and have been finding it difficult building queries with mongoose.
I have a group schema that looks like this :
var groupSchema = new Schema({
title:{type:String, index:true, unique: true, required:true, lowercase:true}
});
and two other schemas, documents, and Users, that reference the groupSchema
User Schema:
var userSchema = new Schema({
//Other datas
group: [{type: Schema.Types.ObjectId, ref: 'Group'}],
});
Documents Schema:
var documentSchema = new Schema({
ownerId:{type:Schema.Types.ObjectId, required: true, ref:"User"},
group:{ type:Schema.Types.ObjectId, ref:"Group", required:true},
});
I would like to fetch all group data and populate them with the documents that belong to that group. I tried using the populate query but it did not work
I have users.js schema with a embeded document array pets. For each user, a user can have multiple pets(usually no more than 3 I would think).
For each pet, there would be a daily chart. So it would be many daily charts for a pet. I have read with embedded documents that each array element is indexed. In daily.js, how can I reference the pet it would belong to for the populate() function?
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
username: { type: String, required: true, unique: true },
location: String,
pets: [{ name: 'string', animalType: 'string'}], //could have more than one pet
created_at: Date,
updated_at: Date
});
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var dailySchema = new Schema({
tite: String,
_pet: { type: Number, ref: 'User.pet' }, // not sure how to reference name in user.pets[#] array
created_at: Date,
updated_at: Date
});
Quoting
Sorry to disappoint but that is an anti-pattern. Populate can't populate from another collection's subdocs - the reason why you're getting that error is that there's no model for boards.
So it may be not good patten to reference to embedded document. It could be better to separate pet from User as one schema
var PetSchema = new Schema ({
name: 'string',
animalType: 'string'
});
And the UserSchema and DailySchema will be
var userSchema = new Schema({
...
pets: [{ type: Schema.Types.ObjectId, ref: 'Pet' }], //could have more than one pet
});
var dailySchema = new Schema({
_pet: { type: Number, ref: 'Pet' }, // not sure how to reference name in user.pets[#] array
});
I am new to mongo and mongoose. I am trying to create 3 collections Users, Articles and Comments. I want the users documents should contain articles that users have saved. The articles object should have users and comments as embedded objects and comments should have embedded user objects.
I want this to be done using the ids of the individual objects so that I can reduce the loading time, but could not find a suitable way to do so using mongoose. Please suggest how should I proceed with the Schema implementation.
var UserSchema = new mongoose.Schema({
name: String,
email: String,
profilePicture: String,
password: String,
readingList: [articleSchema]
});
var commentsSchema = new mongoose.Schema({
content: String,
votes:{
up:[UserSchema],
down:[UserSchema]
},
comments:[commentsSchema],
timestamp:Date.now
});
var articleSchema = new mongoose.Schema({
title: String,
content: String,
image: String,
votes:{
up: [UserSchema],
down: [UserSchema]
},
comments:[commentsSchema],
timestamp: Date.now
});
What you have is failing because articleSchema isn't defined when you're using it in the UserSchema. Unfortunately, you can reverse the order of defining the schema because they're dependent on each other.
I haven't actually tried this, but based on some quick googling there is a way to create the Schema first and then add the properties.
var UserSchema = new mongoose.Schema();
var CommentsSchema = new mongoose.Schema();
var ArticleSchema = new mongoose.Schema();
UserSchema.add({
name: String,
email: String,
profilePicture: String,
password: String,
readingList: [ArticleSchema]
});
CommentsSchema.add({
content: String,
votes:{
up:[UserSchema],
down:[UserSchema]
},
comments:[CommentsSchema],
timestamp:Date.now
});
ArticleSchema.add({
title: String,
content: String,
image: String,
votes:{
up: [UserSchema],
down: [UserSchema]
},
comments:[CommentsSchema],
timestamp: Date.now
});
I have a schema like this
'use strict';
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var TeacherSchema = new Schema({
education: [{degree: String, instituteName: String}],
dob: Date,
photoUrl: String,
phoneNumber: String,
institutes: [{type: mongoose.Schema.ObjectId, ref: 'Institute'}],
subjects: [{
name: String,
topics: [{
name: String,
modules: [{
name: String,
classes: [{
name: String,
startTime: Date,
endTime: Date,
fee: Number
}]
}]
}]
}],
created: {type: Date, default: Date.now}
})
module.exports = mongoose.model('Teacher', TeacherSchema);
My question is how can i query in the nested arrays? To be specific Lets say i want to find all the teachers who have at least one subject/topic/module/class whose name starts with "Math". How can i do that with mongoose?
See if this works...
db.Teacher.find({$or:
[{'subjects':{"$elemMatch":{'name':'Math'}}},
{'subjects.topics':{"$elemMatch":{'name':'Math'}}},
{'subjects.topics.modules.classes':{"$elemMatch":{'name':'Math'}}}]
})
However, I am curious to know why a modules array is needed when all it contains is a classes array?
Let's say you want to search with wildcard "ath"
db.stack30173606.find({$or: [
{'subjects':{"$elemMatch":{'name':'Math'}}},
{'subjects.topics':{"$elemMatch":{'name':'math'}}},
{'subjects.topics.modules':{"$elemMatch":{'name':'Math'}}},
{'subjects.topics.modules.classes.name':{"$in":[/math/]}}
] })
For case insensitive, check this: How do I make case-insensitive queries on Mongodb?