简体   繁体   中英

How to save array of inputs to a child schema in a nested mongoose schema?

I am trying to save a survey which contains multiples questions. Each time I enter a question and the answers and click the save button it should push it to the question array and at last when I click the save survey button the whole question should be saved under the parent schema 'survey'.

How can I do this with nodejs and mongoose? What I tried is here....

Mongoose schema

 var mongoose = require("mongoose");
 var Schema = mongoose.Schema;

 var SurveySchema = new Schema({
    surveyname: String,
    question  : [{
        que: String,
        ans1: String,
        ans2: String,
        ans3: String,
        ans4: String

        }]
    });

 module.exports=mongoose.model('Survey',SurveySchema);

The js file where I save the inputs to the schema

var express = require('express');
var router = express.Router();
var survey = require('../models/QBank');

router.post('/', function(req, res, next){ 
  new survey({
    surveyname: req.body.sname,
    for(var i=0;i<5;i++){
      question.question.push({
        que: req.body.que,
        ans1: req.body.ans1,
        ans2: req.body.ans2,
        ans3: req.body.ans3,
        ans4: req.body.ans4
      });
    }

    }).save(function(err, doc){
      if(err) res.json(err);
      else
          req.flash('success_msg', 'Question saved to QBank');  
      res.redirect("/CreateSurvey");

    });

});

module.exports = router;

I am stuck here with my project.

You can use an atomic update method like findOneAndUpdate() for your post where you can specify the upsert option. If upsert is true and no document matches the query criteria, findOneAndUpdate() inserts a single document. Here that's where you can also use the native $push operator to push the new question and answers to the question array, rather than using a loop when you can let mongo do all the work on the server.

The following example shows how you can refactor your code:

var express = require('express');
var router = express.Router();
var Survey = require('../models/QBank');

router.post('/', function(req, res, next){ 
    Survey.findOneAndUpdate(
        { "surveyname": req.body.sname }, /* <query> */
        { /* <update> */
            "$push": {
                "question": {
                    "que": req.body.que,
                    "ans1": req.body.ans1,
                    "ans2": req.body.ans2,
                    "ans3": req.body.ans3,
                    "ans4": req.body.ans4
                }
            } 
        },
        { "upsert": true }, /* <options> */
        function(err, doc){ /* <callback> */
            if(err) res.json(err);
            else
                req.flash('success_msg', 'Question saved to QBank');  
            res.redirect("/CreateSurvey");
        }
    );
});

module.exports = router;

In the above, the fields and values of both the <query> and <update> parameters are created if the <update> parameter contains update operator expressions. The update creates a base document from the equality clauses in the <query> parameter, and then applies the update expressions from the <update> parameter.

First of all you need to populate your survey object when you enter question and answer and hit save button.Then you can use ajax form submit to send the data to the desired route.

Let's say the survey object is like the following

var randomSurvey = {
   surveyname: "randomSurvey",
   questions:[
             {     
                que: "question1",
                ans1: "answer1"
                ans2: "answer2"
                ans3: "answer3"
                ans4: "answer4"
              },
              {     
                que: "question1",
                ans1: "answer1"
                ans2: "answer2"
                ans3: "answer3"
                ans4: "answer4"
              }
            ]
}

And when you press the save survey button then your post route should be like this.

router.post('/', function(req, res, next){ 

  //Grab your data here sent over ajax form submit 
  var randomSurvey = req.body.randomSurvey;

  var newSurvay = new survey(randomSurvey);

  newSurvay.save(function(err, doc){
      if(err) {
         //do something with err
      }
      else{
        // do something with the result;
      }             
      res.redirect("/your_redirect_url");    
  });
});
var survey = require('../models/QBank');
var Survey = new survey();
var question = [];
question[0] =  req.body.que;
question[1] =req.body.ans1;

// do for all
Survey.question = question;
survey.save(Survey, function(err, doc){})

According to your description you may passed full question to save in DB.

Assumed you passed data in req.body with multiple question. like:

{surveyname: 'your survay name', question: [{que:'q1',ans1:'a1',....},{que:'q2'..},{que:'q3',..}]}

If assumption is correct then can use like:

router.post('/path', function(req, res, next){ 
  var newSurvay = new survey({
    surveyname: req.body.surveyname,
    question: req.body.question
    });

  newSurvay.save(function(err, doc){
      if(err) res.json(err);
      else
          req.flash('success_msg', 'Question saved to QBank');  
      res.redirect("/CreateSurvey");

    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM