How do I search for and display a collection associated with another in Mongoose?

I am currently working on a task to locate and display all questions related to the "Question Collection" that are associated with all the surveys created by a specific user in the "Surveys Collection". Although I have successfully found questions for a particular survey in the list, my goal is to find all questions linked to various surveys.

Here is the progress I have made so far, wherein I am only able to find questions specific to one survey using the _id:

// Display list of user surveys
module.exports.displayUserSurveys = (req, res, next) => {
  let id = req.user._id;

  Survey.find({ User: id }, (err, surveyList) => {
    if (err) {
      console.log(err);
      res.end(err);
    } else {
      let questionId = surveyList[0].Questions;
      Question.find({ _id: questionId }, (err, questionList) => {
        if (err) {
          return console.error(err);
        } else {
          let currentDate = new Date();
          res.render("content/survey/my-surveys", {
            title: "My Surveys",
            page: "my-surveys",
            username: req.user ? req.user.username : "",
            SurveyList: surveyList,
            QuestionList: questionList,
            today: currentDate,
          });
        }
      });
    }
  });
};

Survey Schema:

let surveyModel = mongoose.Schema(
  {
    Title: String,
    Type: [String],
    Questions: { type: mongoose.Schema.Types.ObjectId, ref: "questions" },
    Answered: { type: Number, default: 0 }, // how many times users answered
    User: { type: mongoose.Schema.Types.ObjectId, ref: "users" },
    startdate: { type: Date, default: Date.now },
    enddate: { type: Date, default: Date.now() + 30 * 24 * 60 * 60 * 1000 }, //30 days to milliseconds to set default end date 30 days out
  },
  {
    collection: "surveys",
  }
);

Questions Schema:

let questionModel = mongoose.Schema(
  {
    MC: {
      startdate: Date,
      enddate: Date,
      QuestionText1: String,
      Options1: [String],
      QuestionText2: String,
      Options2: [String],
      QuestionText3: String,
      Options3: [String],
      QuestionText4: String,
      Options4: [String],
      QuestionText5: String,
      Options5: [String],
      
    },
    TF: {
      startdate: Date,
      enddate: Date,
      QuestionText1: String,
      Options1: Boolean,
      QuestionText2: String,
      Options2: Boolean,
      QuestionText3: String,
      Options3: Boolean,
      QuestionText4: String,
      Options4: Boolean,
      QuestionText5: String,
      Options5: Boolean,
    },
  },
  {
    collection: "questions",
  }
);

Would this approach be successful?

// Display list of user surveys
module.exports.displayUserSurveys = (req, res, next) => {
  let id = req.user._id;


  Survey.find({ User: id }, (err, surveyList) => {
    if (err) {
      console.log(err);
      res.end(err);
    } else {
      Survey.aggregate([
        { $match: { User: id }},
        { 
            $lookup : {
                from: "Question",
                localField: "Questions",
                foreignField: "_id",
                as: "questions"
            }
        }
    ]).exec((err, questionList) => {
      if(err) {
        console.log(err);
          res.end(err);
      } else {
        let currentDate = new Date();
              res.render("content/survey/my-surveys", {
                title: "My Surveys",
                page: "my-surveys",
                username: req.user ? req.user.username : "",
                SurveyList: surveyList,
                QuestionList: questionList,
                today: currentDate,
              });
      }
    });
    }
  });
};

Answer №1

If I understand your question correctly, it seems like you are interested in a JOIN operation in SQL. Here is how you can achieve it:

SELECT *
FROM Surveys
JOIN Questions ON Surveys.Questions = Questions._id
WHERE Surverys.User = { UserID }

In MongoDB, you can accomplish a similar operation using Aggregations with the $lookup operator. Here's an example:

const surveys = await Survey.aggregate([
    { $match: { User: id }},
    { 
        $lookup : {
            from: "questions",
            localField: "Questions",
            foreignField: "_id",
            as: "questions"
        }
    }
]).exec()

console.log(surveys)
// Output will show the survey data with associated questions

console.log(surveys[0])
// Output will display the first survey data

console.log(surveys[0].questions[0].MC.QuestionText1)
// Output will show the first questionText

One suggestion is to consider nesting the Questions within the survey if there is a 1-to-1 relationship, instead of using separate Collections.

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

When a page is changed, the Vue.js Active Menu color remains enabled

Check out my website at . I want to customize the navigation bar so that only the active page's navbar li is colored in red. <div class="navigation-items"> <ul class="nav-list"> <li class="nav-item"><nuxt-link to="/en" ...

Add custom scripts to individual components within a Vue.js application

After extensive searching, I still can't seem to find a solution to my current issue. My focus is on a Vue project with vue-cli, where I need to inject various scripts into different pages (leveraging vue-router). Here are more specific details: Thi ...

Issue with Vue's v-autocomplete component not clearing the user's typed text when an item is selected from

I have implemented a vue v-autocomplete component on my page. I am unsure if the current behavior is as expected, as I cannot find similar examples demonstrating this functionality. The issue arises when a user begins typing in text and the autocomplete ...

Vue.js is displaying one less item

Recently I started working with Vuejs and encountered an unexpected issue in my application. The purpose of my app is to search for channels using the YouTube API and then display those channels in a list. However, when I try to render the list of subscri ...

Using Node JS to pass variables to the client

Currently, I am utilizing Node JS and Express for my server-side needs. In my server-side code, I pass a variable (sources) to my EJS template. Part of this variable is used to populate a list on the webpage. However, when a user clicks on an item in the ...

The addition of a cancel swipe feature to an HTML5 eBook is causing the text input field for note-taking to malfunction

I am currently working on the development of a process to create HTML5 based eBooks for both desktop and mobile use using Adobe InDesign and exporting them with a plugin called In5. This plugin allows for the incorporation of html, css, and javascript duri ...

Is randomly pairing 2 datapairs after slicing a JSON array easy or challenging?

There is a JSON file containing an unlimited number of users [{ "fname": "Hubert", "lname": "Maier", "email": "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="bd ...

Adjust the height of the Iframe to match the content within it

After conducting my research, I have not been able to find a solution. Although I am not an expert in jQuery, it seems that the code is not functioning properly. Within the iframe are links that expand when clicked to display content. However, the height o ...

Is there a versatile Node.js HTTP request module that is compatible with both server-side and browser-side development, particularly when packaged with Webpack?

Currently, I am searching for a request module that can operate seamlessly in both the Node.js server and the client when compiled with Webpack. The requirements are quite straightforward. I simply need to execute some basic HTTP Ajax requests such as get ...

Sorting at the server side is not happening

I am having trouble with server-side sorting using ORM Sequelize. By default, the sorting is supposed to be done by name in ascending order. However, when I try to change it to descending order on the client side, nothing happens despite seeing the request ...

Leveraging jQuery to interact with MySQL database in PHP Laravel framework

I seem to have hit a roadblock with my database, which is quite intricate. Here's the breakdown of the tables used for the questions: product - contains product details such as shoes productattribute - houses different variations of products like bl ...

My JavaScript code is functioning properly in jsfiddle, but when I try to run it on my own website, I encounter

Encountered an error message stating "Uncaught typeError: cannot call method 'hover' of null" following the line $('#nav li a').hover(function(){ in my JavaScript code. Check out the code on my site here: http://pastebin.com/GjZBEu3s Y ...

Encountering issues with uploading Cloudinary images through Nodejs

I'm having trouble uploading a base64encoded image to Cloudinary using the code snippet below. It's not working as expected and I keep getting a 500 error when making the post request. Can anyone provide me with a solution or suggest what might b ...

I need to know how to create a patch request in Vue.js and simultaneously modify the marks input for specific individuals by using v-model

Hello there, I am currently developing a student assessment input form using vuejs, express, and mongoDB. The backend API is complete and functioning properly when tested with postman. Here is the code: // UPDATE MARKS router.patch('/:studentId' ...

jQuery and Easy Dialog

My jQuery Model window has a form inside. Even though I have set autoOpen to false in my dialog, the fields are still visible when the page is created. All forms are contained within a div. This is what my dialog code looks like: $("#dialog-form").dial ...

Every time I make a call, Spring keeps mentioning that the Repository is null

Encountering a recurring error that states: java.lang.NullPointerException: Cannot invoke "com.example.cinema.Repository.VideosRepository.save(Object)" because "com.example.cinema.Service.VideoService.videoRepository" is null The same error occurs when a ...

`How can you utilize typeahead.js to showcase images on your webpage?`

Is there a way to show images using typeahead.js? I am attempting to include profile images in the list generated by typehead.js. Currently, I can only display text in the list as shown below: This is how my javascript appears: Along with my PHP code w ...

Creating multiple countdowns in AngularJS using ng-repeat is a handy feature to have

Currently, I have a small AngularJS application that is designed to search for users and display their upcoming meetings. The data is retrieved from the server in JSON format, with time displayed in UTC for easier calculation to local times. While I have s ...

Maintaining my navigation menu as you scroll through the page

I've been working on creating a website for my business but I'm facing a challenge. My goal is to have a fixed navigation bar that stays in place as people scroll down the page, similar to what you can see on this website: (where the navigat ...

Having trouble with your contact form and not getting it to work properly with Javascript, Ajax, or

I've been struggling to get a contact form working for an entire day. I included the following script at the top of my page: <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script> This is the structure ...