简体   繁体   中英

Mongoose nested schema

I want to make a system of topics. each topic may have subtopics which are also topics. meaning the subtopics may also have subtopics. for example example image

I tried to create a topic schema and add a subtopic field which will ref to topic schema too. cant seem to get this working my schema code:

const mongoose = require('mongoose');

const TopicSchema = new mongoose.Schema({
    name: {type:String,unique:true},
    sub_topic:[{type:mongoose.Schema.Types.ObjectId, ref : 'Topic'}] 
});

const Topic =mongoose.model('Topic', TopicSchema);
module.exports = Topic;

Also what the data im sending to the server should look like to make a new instance? and on the server how do i save it?

i try to save like this now : const topic = new Topic();

topic.name = req.body.name;
topic.sub_topic.name=req.body.sub_topic

and the data im sending is :(json)

{
    "name":"TestMain",
    "sub_topic":[{"name":"TestSub"}]            
}

UPDATE : got this done using a recursive function.

function subtopicHandler(topic, sub_topic) {
    Topic.find({
      "name": topic.name
    }, function (err, res) {
      if (err) throw err
      return;
    })

    if (sub_topic == undefined) {
      let ntopic = new Topic();
      ntopic.name = topic.name;
      ntopic.sub_topic == undefined;
      ntopic.save(function (err, result) {
        if (err) console.log('saving err', err)
      });
      return ntopic._id;
    }
    let mainTopic = new Topic();
    mainTopic.name = topic.name;
    sub_topic.forEach(function (sub) {
      mainTopic.sub_topic.push(subtopicHandler(sub, sub.sub_topic));
    })
    var retME;
    mainTopic.save(function (err, result) {
      if (err) {
        console.log('saving err', err)
        throw err;
      }
    });
    return mainTopic._id;

  }

Using this schema :

const TopicSchema = new mongoose.Schema({
    name: {type:String,unique:true},
    sub_topic:[{type:mongoose.Schema.Types.ObjectId, ref : 'Topic'}] 
});

and data sent as :

{
    "name":"A",
    "sub_topic":[
                    {"name":"C","sub_topic":
                        [
                            {"name":"C1"}
                            ,
                            {"name":"C2"}
                        ]
                    }
                    ,
                    {"name":"B"}
                    ,
                    {"name":"D","sub_topic":
                        [
                            {"name":"D1"}
                            ,
                            {"name":"D2"}
                            ,
                            {"name":"D3"}
                        ]
                    }
                ]            
}

to the API endpoint handled this way:

let mainTopic = new Topic();
    mainTopic.name = req.body.name;
    subtopicHandler(mainTopic, req.body.sub_topic);
  })

If you are sending following json

const obj = {
    "name":"TestMain",
    "sub_topic":[{"name":"TestSub"}]            
}

Then,

let mainTopic = new Topic();
let subTopic = new Topic();

// assuming for now you have only one sub-topic in array
subTopic.name = obj[0].name;

subTopinc.save(function(err,result)=>{
    if(!err){
        mainTopic.name = obj.name;
        mainTopic.sub_topic = [result._id]
        mainTopic.save(function(err,result){
            console.log(result);
        })
    }
});

From you schema definition and the given json you can follow the above step to get the results.

Hope this will help you.

You can do this with sub docs check out the documentation.

https://mongoosejs.com/docs/subdocs.html

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