How to structure various interdependent Schemas in mongoose OR how to use 'reference' properly?

visionInc Source

I'm currently working on a vocabulary application using node.js, Express, MongoDB and mongoose.

My aim: Putting out translations for various languages depending on the choices made in the front-end (E. g.: German > English, English > Portuguese etc.)

Main problem: Interdependent Schemas. The translation of a word stored in WordSchema depends on the language represented by the LanguageSchema.

For me, there appear two different ways on how to structure the relevant Schemas:

1. There is one Schema representing the language (e.g. German, Englisch,...). It stores several words according to the language. Because Word represents another Schema it is referenced to the WordSchema inside the LanguageSchema. The problem which appears here is that the values of the word depend on the chosen language.

var Schema = mongoose.Schema;

var LanguageSchema = new Schema({
    language: String, // 'German'
    words: [{type: Schema.ObjectId, ref: 'Word'}] 
    // word: 'Haus' instead of e. g. 'house'
});

module.exports = mongoose.model('Language', LanguageSchema);

var WordSchema = new Schema({
    name: String // 'house', 'Haus', 'casa' depending on the language
});

module.exports = mongoose.model('Word', WordSchema);

2. I could solve this by using just the WordSchema and adding all the languages which exist as a property and add the according translation of the word. But this doesn't seem the best working solution for me as I won't translate the words into all languages right from the beginning. So there just should be stored those translations for a word where there actually exists a translation.

javascriptnode.jsmongodbmongoose

Answers

answered 6 months ago Saurabh Mistry #1

LanguageSchema

var Schema = mongoose.Schema;

var LanguageSchema = new Schema({
    language_name: {type:String}, // English
    language_code: {type:String}  // en
});

module.exports = mongoose.model('Language', LanguageSchema);

In Word Schema , you need to push objects with word_name and word_language

WordSchema

var WordSchema = new Schema({
    words:[{
                  word_name:{type:String},
                  word_language:{type:String}
                 }]
});


module.exports = mongoose.model('Word', WordSchema);

Example : Language in Database

    languages : [
                  { 
                    "_id":"54ef3f374849dcaa649a3abc", 
                    "language_name":"English" , 
                    "language_code":"en"
                  },
                  {
                   "_id":54ef3f374849dcaa649a3asd",   
                   "language_name":"Portuguese" , 
                   "language_code":"pt"
                   },
                  {
                   "_id":54ef3f374849dcaa649a3xxx", 
                   "language_name":"German" ,
                   "language_code":"de"},
                ]

Example : Words in Database

  words:[
       {
       word:[
        {
         "_id":"54ef3f374849dcaa649azzz", 
         "word_name":"Friend" ,
         "word_language":"English"
        },

        {
         "_id":"54ef3f374849dcaa6491111",
         "word_name":"Amigo" ,
         "word_language":"Portuguese"
        },
        {
        "_id":"54ef3f374849dcaa649a233",
        "word_name":"Freund" ,
        "word_language":"German"
        },
       ]
     },
     { word: [...] },
     { word: [...] },
     { word: [...] },
     { word: [...] }
 ]

from frontend you have to pass 3 parameters

word , input_language , output_language

Example : You want "Friend" meaning from English to Portuguese

so in this case :

word="Friend" , input_language="English" , output_language="Portuguese"

Now Applying Mongoose Find Query and search Word in WordSchema

Word.findOne({word_name:{ $regex:word, $options: "$i" },word_language:input_language},function(err,result){
    if(err){ return err;}
    if(!err && result){
 //  now you have to use underscore.js and find out result by output language 

//  http://underscorejs.org
// . npm i --save underscore 

      var outputObj= _.find(result.word, { word_language :output_language});

      res.json(outputObj);

    }
})

comments powered by Disqus