Utilizing a separate schema within Mongoose

Suppose I have two schemas defined as follows:

var userSchema = new Schema({
    twittername: String,
    twitterID: Number,
    displayName: String,
    profilePic: String,
});

var  User = mongoose.model('User') 

var postSchema = new Schema({
    name: String,
    postedBy: User,  //User Model Type
    dateCreated: Date,
    comments: [{body:"string", by: mongoose.Schema.Types.ObjectId}],
});

I attempted to link them together like in the example above but encountered difficulties. In the end, being able to accomplish this would greatly simplify my tasks.

var profilePic = Post.postedBy.profilePic

Answer №1

If you're searching for a solution, the populate method seems to be what you need. Start by making a small adjustment to your post schema:

var postSchema = new Schema({
    name: String,
    postedBy: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
    dateCreated: Date,
    comments: [{body:"string", by: mongoose.Schema.Types.ObjectId}],
});

Next, create your model:

var Post = mongoose.model('Post', postSchema);

Finally, when executing your query, you can populate references in this manner:

Post.findOne({_id: 123})
.populate('postedBy')
.exec(function(err, post) {
    // perform actions with post
});

Answer №2

Just a heads up: If you haven't already, take a look at "Populate" in Mongoose — it's definitely worth exploring and understanding how it handles cross-document referencing.

http://mongoosejs.com/docs/populate.html

Answer №3

Although it's a delayed response, Mongoose also introduces the concept of Subdocuments

By using this syntax, you can specify your userSchema as a data type in your postSchema, like this:

var userSchema = new Schema({
    twittername: String,
    twitterID: Number,
    displayName: String,
    profilePic: String,
});

var postSchema = new Schema({
    name: String,
    postedBy: userSchema,
    dateCreated: Date,
    comments: [{body:"string", by: mongoose.Schema.Types.ObjectId}],
});

Take note of the revised postedBy field with a data type of userSchema.

This approach embeds the user object within the post itself, eliminating the need for an additional lookup that would be required when using references. Depending on the context of your application, embedding may be more beneficial at times while using ref/populate could be preferred in other scenarios. It all depends on the functionality of your application.

Answer №4

Diving deeper into D. Lowe's response that initially helped me but required some adjustments. (I wanted to leave this as a comment, but I lack the necessary reputation points. Plus, I want to ensure I can refer back to this information in a few months when faced with a similar issue and forget how to resolve it.)

If you're bringing in a Schema from another file, make sure to include .schema at the end of the import statement.

Note: While unsure whether using local schemas instead of importing them could trigger an Invalid schema configuration error, personally, I find importing cleaner and more manageable.

For instance:

// ./models/other.js
const mongoose = require('mongoose')

const otherSchema = new mongoose.Schema({
    content:String,
})

module.exports = mongoose.model('Other', otherSchema)

//*******************SEPARATE FILES*************************//

// ./models/master.js
const mongoose = require('mongoose')

//If you omit .schema at the end, you'll encounter the "Invalid schema configuration: `model` is not a valid type" error
const Other=require('./other').schema


const masterSchema = new mongoose.Schema({
    others:[Other],
    singleOther:Other,
    otherInObjectArray:[{
        count:Number,
        other:Other,
    }],
})

module.exports = mongoose.model('Master', masterSchema);

You can then easily assign 'other' to 'master' whenever needed (e.g., in my Node.js API).

For example:

const Master= require('../models/master')
const Other=require('../models/other')

router.get('/generate-new-master', async (req, res)=>{
    //load all others
    const others=await Other.find()

    //generate a new master from your others
    const master=new Master({
        others,
        singleOther:others[0],
        otherInObjectArray:[
            {
                count:1,
                other:others[1],
            },
            {
                count:5,
                other:others[5],            
            },
        ],
    })

    await master.save()
    res.json(master)
})

Answer №5

{body: "string", by: mongoose.Schema.Types.ObjectId}

Instead of using mongoose.Schema.Types.ObjectId to create a new id, consider changing it to a more specific type like String or Number.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering a 500 error while attempting to send data to an API route within a Laravel web page using XMLHttpRequest at http://127:8000/api/v1/exemp. Can anyone

let requestData = { products: [ { description: "product1", barcode: "123456", price: 10, note: "note1" }, { description: "product2", barcode: "654321", price: 20, note: "note2" ...

Using Javascript to fetch undefined data from a C# backend with AJAX

I am struggling to create a web page using Google charts. I attempted to build it with C# as a web form and retrieve data from a local database to JavaScript. However, I keep receiving an error stating that the data is undefined in the response from Ajax. ...

Inconsistent display of Bootstrap tooltip upon mouseover

Utilizing an icon from Font Awesome to showcase text in a tooltip upon mouseover with Bootstrap, I encountered an issue where the tooltip only displays when hovering over the left half of the icon. This discrepancy occurs on both Edge and Chrome browsers, ...

Change the size of a particular div upon hovering over another element

I'm trying to figure out how to scale my div with text when a user hovers over a button, but I've tried various operators like >, ~, +, - with no success. section { background: #000; color:#fff; height: 1000px; padding: 150px 0; font-family ...

Keep the Bootstrap dropdown menu open when the search bar is in focus

I am working on a customized bootstrap dropdown menu that needs to remain open when the search bar within the Events dropdown is focused. I have managed to make it open and close on hover, but now I need it to stay open under certain conditions. Below is ...

I am utilizing the useEffect hook along with Axios to fetch data from the backend. My goal is to retrieve two arrays of objects in order to render them on the

I am attempting to retrieve 2 arrays of objects from my MySQL database using Axios, but the console.log output '3' is showing an empty array. I'm not sure what's causing this issue. export default function Editar() { let {clienteId} = ...

Is the integration of async prior to the created method in Vue disrupting the lifecycle?

Is it advisable to include async before the created method in Vue.js? Won't this disrupt the Vue life cycle since using async makes it an asynchronous action that gets sent to the background queue, potentially allowing methods like mounted to execute ...

Adjusting font size in dynamic containers relatively

Imagine we have a slider named .outer, which adjusts its height based on the width of the viewport. Inside this slider, there is an example slide called .inner that contains some text. However, when we shrink the window width, the content in slide .inner s ...

Is it possible for a button to simultaneously redirect and execute a function using asynchronous JavaScript?

After browsing through several related posts, I realized that most of them were using href to redirect to a completely new webpage. However, in my JavaScript code, I have a button that utilizes the Material-UI <Link>. <Button component={Link} to= ...

The socket context provider seems to be malfunctioning within the component

One day, I decided to create a new context file called socket.tsx: import React, { createContext } from "react"; import { io, Socket } from "socket.io-client"; const socket = io("http://localhost:3000", { reconnectionDela ...

Running of code in <script> tag

At what point does the code inside script tags start executing? Does it happen in order? <html> <head> <title>Canvas tutorial</title> <script type="text/javascript"> function draw(){ var canvas = document.getElementById ...

Attempting to execute npm install for an Odin project task, encountered the error "Module not Found". // A new error has surfaced, continue reading below

Trying to run npm install for the Odin Project JavaScript Fundamentals Part 4 lesson has been quite a challenge. Initially, upon forking and cloning the repository and running npm install as per the instructions, I encountered a permission error. However, ...

Deactivate the ajax submission button when a key is pressed

There is a button on my Ajax form that, when clicked, displays to the user that it is currently "searching" by showing a small loading symbol while the database is being queried. Upon clicking the submit button, it triggers a function. This function disab ...

Updating the configuration settings for CKEditor 5 using Reactjs

I followed the configuration provided in another answer at But, I am facing an issue: Failed to compile. ./src/components/cards/CreateCard.js Line 59:22: Parsing error: Unexpected token, expected "}" 57 | editor={ClassicEditor} 58 | ...

Animate the parent container of ng-view in Angular by targeting an element within ng-view

Are you able to use CSS animations to animate a div's background color that is located outside of the ng-view, while using a directive on a $state within the ng-view? The ng-view already has CSS animations for routing. When I try to add animation cl ...

Is there a way to create a list in w2ui without including the -none- option?

Is there a way to create a list (select) in w2ui forms without the default -none- option? I would like to remove the default option and only display the items that I add to the list. How can this be achieved? ...

Brother or sister is never empty, as every comment is considered an entity

When going through a list of jQuery objects, I want to verify if the nextSibling attribute is null. However, I found that an HTML comment also counts as a sibling object. How can I address this issue? I am looking for an if statement that will trigger fo ...

What could be causing an undefined error when running Javascript with Python and Selenium?

My goal is to utilize Javascript for retrieving a table body element on a webpage. Upon executing the script immediately, I receive an undefined response. However, if I introduce a few seconds delay, it functions correctly. def fetch_row_list(browser): ...

What is the best method to retrieve the page title in Nuxt 3?

I can't seem to figure out how to retrieve the page title in Nuxt 3 and use it in a layout. I'm convinced that it must be possible through some kind of meta object, but I just can't seem to find it. I attempted to access it through route me ...

Combining various FormGroup types into a single object type in Angular 5

I am currently utilizing the mat-stepper feature from the Angular Material design library. Within my application, I am using 3 separate FormGroups to gather information and send it to a database using the httpClient method. To achieve this, I have defined ...