Using 2 connections in mongoose in nodeJS - javascript

I want to use 2 or more different databases simultaneously, these 2 connections have different properties. And according to database selection data should be displayed. Its dynamic db switch in mongoose if anyone have any idea please help.
Lets say there is a model
var mongoose = require('mongoose');
var Promise = require("bluebird");
mongoose.Promise = Promise;
var Schema = mongoose.Schema;
var uomSchema = new Schema({
uom: {
type: String,
required: [
true,
"Please enter valid uom"
],
elementType: "TEXT",
elementText: "Unit Of Measure",
placeholder: ""
}
}, { strict: false });
var uom = mongoose.model('uom', uomSchema);
module.exports = uom;
so here it creates model over default connection foo, so if there is another connection bar and over that db needs to create same model to operate over data, how is that possible ?
mongoose-glue provide somewhat similar solution, but not exact that I want

Maintain one json file in that { "db1":"asas" , "db2":"xczc" } and while connecting to db fetch db name from this json file as
var conUrl = config.db1 OR db2 as per your condition

Related

Populating an Object with Information from a Child Object with Different Model (JS/Mongoose)

Here is what I have. I created a project model that references a user model for an array of members.
var ProjectSchema = new mongoose.Schema(
{title: {
type: String,
required: true
},
members: [
{user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users'
}
}],
});
User Schema (I have code that creates a model from both of these schemas)
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
}
});
In a separate file, I want to export the JSON of a found project and include the information of the users in the members array, but I am not sure how to do that. This is the code I have right now.
const project = await Project.findById(req.params.proj_id).populate(
'members'
);
res.json(project);
It has no trouble finding the project but the only information I can get on the members is their id. I tried using for loops to gather the information from members separately using the id that I can get from the project, but the code gets messy and I am hoping to find a simpler way to do it.
You can use mongoose populate query to get all members associated with a project. It should populate array of objects users associated to a project. You should be doing something like this:
const project = await Project.findById(req.params.proj_id)
await project.populate('members').execPopulate()
console.log(project.members)
Mongoose docs for the reference: Populate
You can give the model to your mongoose populate.
const project = await Project.findById(req.params.proj_id)
.populate({
'members',
model: UserModel
})
.exec()
res.json(project);
keep in mind you've to create UserModel just like
const UserModel = mongoose.model('User', userSchema);

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

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.
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);
}
})

Using "#" in key when inserting to MongoDB with mongoose

Mongoose schema won't let me use # sign in key when inserting to MongoDB with using Node.js. For instance:
var blogSchema = new Schema({
#context : Object //error illegal token
#id : String // illegal token
}, {strict: false});
I tried key with unicode characters like this one:
"\u0040context" = Object // ignored unicode, inserted as context
"\x40context" = Object // ignored unicode, inserted as context
\x40context = Object // illegal token
Also tried with normal way using this link(first way), still cannot define key with #:
http://blog.modulus.io/mongodb-tutorial
My purpose is to create document with using JSON-LD format which requires of using # symbol in key. How to accomplish this? Here are the similar links I have looked for solution:
variable with mongodb dotnotation
Syntax error Unexpected token ILLEGAL Mongo Console
How to use mongoose model schema with dynamic keys?
How to do a query using dot( . ) through Mongoose in Node.js and How to add an empty array
Create a Schema object in Mongoose/Handlebars with custom keys/values
http://mongoosejs.com/docs/schematypes.html
You can use directly # between quotes such as "#field" :
"use strict";
var mongoose = require('./node_modules/mongoose');
var Schema = mongoose.Schema;
var db = mongoose.connection;
var itemSchema = new Schema({
"#field": {
type: String,
required: true
},
"#field2": {
type: String,
required: true
}
});
var Items = mongoose.model('Items', itemSchema);
var db = mongoose.connect('localhost', 'testDB');
Items.create({ "#field": "value", "#field2": "value" }, function(err, doc) {
console.log("created");
if (err)
console.log(err);
else {
console.log(doc);
}
db.disconnect();
});

Load only required plugin into the Schema when saving a model

Plugins is quite a powerful feature in Mongoose.js, but there is one thing I have got stuck with. I need to load only the required plugin into the Schema when saving a model. Because If I don't do it, the other unnecessary plugins are loaded automatically along with lots of validation errors.
Here is my schema
// models/user_collection.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
username: { type: String, required: true },
password: { type: String, required: true },
role: String // either 'memeber' or 'admin'
});
// Member User Plugin
UserSchema.plugin(function (schema) {
schema.add({
locality: { type: String, required: true },
contactNo: { type: Number, min: 13, max: 13 }
});
});
// Admin User Plugin
UserSchema.plugin(function (schema) {
schema.add({
accountNo: { type: String, required: true },
settingsArray: Array
});
});
mongoose.model('User', UserSchema);
Now whenever I try to save a record only for member user, the Schema automatically loads the Admin plugin, responding with validation errors.
So,
var member = new User();
member.username = 'XYZ';
member.password = createHash('ABC') // a hashing method;
member.role = 'member';
member.locality = 'USA';
member.contactNo = 123456;
member.save(function(err, user) {
if(err) { console.log(err); res.send(err); return; }
// if successful I do my stuff
});
As soon as the save method is executed, I get validation errors from Admin like
"accountNo is required", ( I am not gonna paste the stack trace here, it will get messy, but you got the point )
Now I know that it is not an issue or bug with Mongoose.js, but I am doing something wrong here. Can you guys please guide me how to do it correctly ?
The thing is you are applying both the plugins to the same schema. So all the plugin functionality is being added to the schema. So accountNo and locality is required. Plugins are used to define common code at one place and use it across different schemas.
The way you have used plugins here, you just have broken down the definition of the model to smaller parts. You could as well put everything under the schema and would have gotten the same effect.
Read about plugins again.
As you said, I guess Discriminators is the way to go.

Defining a property on mongo schema referencing another schema plus extra fields

I am trying to define a mongo Schema using mongoose. I need to create an 'Event Schema' in which users are referenced. So I am populating the 'users' field with the referenced ObjectId of the user Schema. However I also need to add some extra fields on that user property which are specific to the event. So something like as follows:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var EventSchema = new Schema({
name: String,
date: Date,
users: [{
profile: {
type: Schema.ObjectId,
ref: 'User'
},
RankNumber: Number,
bibNumber: Number
}],
published: Boolean
});
mongoose.model('Event', EventSchema);
However this doesn't work. I am not sure the best way to do what I am trying to achieve.
So if I have a constructor function such as:
function User(bib, rank, profile) {
this.bib = bib;
this.rank = rank;
this.profile = profile;
}
and then I call that constructor and pass in a user id as the profile property, MongoDB will create a new id field. I get a JSON response like this:
{
"name": "Event name",
"_id: "mongoid",
"users": [
{
"bibNumber": "278",
"rankNumber": "21",
"profile": "users mongo _id number",
"_id": "a new mongo _id"
}
]
}
I need to populate the profile field. But the following won't work:
Event.find().populate('users').exec(function (err, events) {....
You have to use, as I said in the comments:
Event.find(...).populate('users.profile').exec(...);

Categories