populating inner attribute within sub object in mongoose document - mongodb

I have a following type of schema and I want populate the guide details when getting a tour document. I tried with Tour.findById(id).populate({path: 'summary.guide'}). But in the result it returns a null for guide. How to populate that guide details?
const tourSchema = new mongoose.Schema({
from: String,
to: String,
summary: {
guide: { type: Schema.Types.ObjectId, ref: 'User' },
duration: Number,
distance: Number
}
})

I think you should not pass the user id into the summary.guide object.
The second possibility is user id and summary.guide not match.
The third possibility is summary.guide is not exist.
this code works for me
Tour.findById("5dcd2c61...").populate({path: 'summary.guide'});

Related

How to use Object type in mongose schema?

I am trying to store the amount of time an employee has worked in my MongoDB database, but not able to make a mongoose schema whose type will object.
The desired database should have a document like this:
{
name: 'name of employee',
report: {'01-01-2023':5hr, '02-01-202':7hr, '03-01-2023':8hrs}
}
This report will contain an object whose key will be a date and the value will be minutes or hours an employee has worked on that date.
how can I make a schema to achieve the desired goal, I have tried like this but did not work.
const UserSchema = new mongoose.Schema({
name:{
type: String,
required: true
},
report: {
type: Object, // what should I write here
}
})

Best practices with connecting data from 2 models

I've got two models: Note and Profile. Note contains foreign key of connected profile as you can see below.
Note: {
profile_id: String,
date: String,
content: String,
}
Profile: {
id: String,
name: String,
profilePicture: String
}
I want to get all notes and also name and profile picture of note.
In this situation should I:
get all notes and all profiles and then join them locally in for loop,
get all notes and then in for loop ask DB for name and picture of matching profile,
other option
Which way is recomended?
Take a look at mongoose's Populate. You can declare a Schema property with type: Schema.Types.ObjectId, ref: 'Profile'. When you run a Query you can .populate() this field with the corresponding document.

Cannot set the reference to the user document in courses mongoose

I am currently working on a RESTful API, and I am trying to reference the users schema in the courses document such that, when a POST request gets sent to the route of the course, a course is created in the DB and has as one of its fields a reference to the user that created it. However, for the life of me, I cannot figure out why the "user" field is not appearing when I post. There seem to be quite a few of these questions here on Stack so I may just be adding to the pile, but I tried their solutions and they did not work for me
var mongoose = require('mongoose')
var Schema = mongoose.Schema
var userSchema = new Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
emailAddress: {
type: String,
required: true
},
password: {
type: String,
required: true
}
});
var CourseSchema = new Schema({
user: {type: Schema.Types.ObjectId, ref: 'User'}, //FOR some reason this is not showing up on any courses created using the
title: {
type: String,
required: true
},
description: {
type: String,
required: true
},
estimatedTime: {
type: String
},
materialsNeeded: {
type: String
}
});
var User = mongoose.model('User', userSchema);
var Course = mongoose.model('Course', CourseSchema);
module.exports = {Course, User};
Do you see anything in here that would preclude the user field from appearing when a new course is created?
I have attached some screenshots to further explain.
This first image is a screen of the currently authenticated user credentials (fake data obviously). This is the user that is sending the POST request for the new course. I would expect his information to be attached to the course (see screenshot 3)
This image shows the body of the request that is sent. You can see that the key-value pairs match what is in the CourseSchema. I would expect that the "user" field would be created once the POST request is sent.
This last image is some dummy data that is the expected result.
Thanks all for taking a look at this!
User field will not be automatically added to the course document. You have to manually set the user field in the request body itself or while creating a course.
Example of the course body to be sent:-
{
user: "userId",
title: "test",
description: "test",
estimatedTime: "test",
materialsNeeded: 1
}
Also, the result of this will not include the whole user document as you have mentioned in the expected result. It will only return the userId. However, while accessing the course you can populate the user field to get the whole user document. Example for the same
Course.find({...query}).populate("user")

Mongoose mixed SchemaType

I couldn't understand that for what purpose mongoose schemaType is used for. If someone could explain it will be helpful.
I'm have to reference another schema from a schema i want to know if we can get the details of all schema together when we do a findOne() on mongoose.
mixed schema means whatever you want the type to be. if you input a String, Number, Date, mongoose will let you do that. However according to documentation, mongoose ref does not work with mixed.
Note: ObjectId, Number, String, and Buffer are valid for use as refs.
if you use mixed, and ref it, you won't be able to query it back.
If you start all over(delete the database and reinsert again), use ObjectId instead of Mixed.
var storySchema = Schema({
author : { type: ObjectId, ref: 'Person' },
});
If you wish to retain old database, the best way is to change mixed to string
var storySchema = Schema({
author : { type: String, ref: 'Person' },
});

How to dynamically populate mongoose document reference at runtime?

I have a schema that has a field that could reference different schema.
var HistorySchema = new Schema({
type: {type: String, required: true},
objectId: {
type: Schema.Types.ObjectId,
required: true,
},
changed: {type: Schema.Types.Mixed}
})
The documents of this schema allows me to keep track of changes happens in different types of objects with objectId.
For example, if User has changed name from 'John' to 'Steve', a History document would have:
{
type: 'User',
objectId: '55fa6bf0831ba3fa0879e7e8',
changed: {name: {oldValue: 'John', newValue: 'Steve'}}
}
Obviously, type can be many different things.
My question is, can I magically populate the objectId field without knowing type before the query?
I know I can do:
History.query({...}).populate('objectId', null, 'User').exec(...);
But that requires me to know the type is User when the query is constructed.
And obviously I can do a second query manually given the type and objectId.
For example, is it possible to save the ref type of a document (not schema) at runtime and take advantage of that? I look around and don't seem to find a way.