Mongoose multiple connections - node.js

Currently I have this code for my connection mongoose.js:
var mongoose = require('mongoose');
var uriUtil = require('mongodb-uri');
var mongodbUri = 'mongodb://localhost/db_name';
var mongooseUri = uriUtil.formatMongoose(mongodbUri);
mongoose.connect(mongooseUri);
module.exports = mongoose;
File that requires the connection is test.js:
var mongoose = require('../model/mongoose');
var schema = mongoose.Schema({...});
How can I update mongoose.js to use multiple connections with mongoose.createConnection(...) function?
I start with changes only for one connection when I do changes like that:
var mongoose = require('mongoose');
mongoose.createConnection('mongodb://localhost/db_name');
mongoose.open('localhost');
module.exports = mongoose;
I get "undefined is not a function".
If I use this code:
var mongoose = require('mongoose');
db = mongoose.createConnection('mongodb://localhost/db_name');
db.open('localhost');
module.exports = mongoose;
I get "Error: Trying to open unclosed connection"
Any advice?

Mongoose handling connections via connections pool
http://mongoosejs.com/docs/connections.html
You can use server: {poolSize: 5} option for increase/decrease pool (number of parallel connections)
If you need connections to different databases look here
Mongoose and multiple database in single node.js project
Example of multiple connections:
var mongoose = require('mongoose')
var conn = mongoose.createConnection('mongodb://localhost/db1');
var conn2 = mongoose.createConnection('mongodb://localhost/db2');
var Schema = new mongoose.Schema({})
var model1 = conn.model('User', Schema);
var model2 = conn2.model('Item', Schema);
model1.find({}, function() {
console.log("this will print out last");
});
model2.find({}, function() {
console.log("this will print out first");
});

OK. With your example I found a solution that fit my needs.
mongoose.js
var mongoose = require('mongoose');
mongoose.main_conn = mongoose.createConnection('mongodb://localhost/main');
mongoose.admin_conn = mongoose.createConnection('mongodb://localhost/admin');
module.exports = mongoose;
content.js
var mongoose = require('../model/mongoose');
var schema = mongoose.Schema({...});
/// functions here
schema.statics.func_a(){...};
schema.statics.func_b(){...};
// And finaly updated only one line
//exports.Content = mongoose.model('Content', schema);
exports.Content = mongoose.main_conn.model('Content', schema);
The only thing, is it OK to add connection objects to mongoose object or may be there is more elegant solution.

config.js
module.exports = {
default: 'main',
main: 'mongodb://localhost/main',
admin: 'mongodb://localhost/admin',
};
connection.js
const mongoose = require('mongoose');
const config = require('./config');
mongoose.Promise = global.Promise;
function createConnection(name) {
return mongoose.createConnection(config[name]);
}
module.exports = createConnection(config[config.default]);
module.exports.on = createConnection;
model.js (custom class)
const connection = require('./connection');
class Model {
constructor(name, data) {
this.data = data;
return this.connection().model(name, data.schema);
}
connection() {
if (this.data.connection) {
return connection.on(this.data.connection);
}
return connection;
}
}
module.exports = Model;
user.js
const Schema = require('mongoose').Schema;
const conn = require('./connection');
const Model = require('./model');
const userSchema = new Schema({
name: String,
email: String,
password: String
});
// USING MONGOOSE MODEL
// default connection
const UserM1 = conn.model('User', userSchema);
// admin connection
const UserM2 = conn.on('admin').model('User', userSchema);
// USING CUSTOM MODEL
// default connection
const UserC1 = new Model('User', {
schema: userSchema
});
// admin connection
const UserC2 = new Model('User', {
schema: userSchema,
connection: 'admin'
});

Related

Mongoose create multiple Connections

I'm following Mongoose Connection Docs to create multiple Databases Connections on express app. When i import my schema scoped to a connection i can't use models functions such like .find || .findOne etc.. and i get the next error
UserSchema.find is not a function
Is there something that i miss to add or is something i'm making wrong ??
Here is Schema code:
models/user.js
const { Schema } = require('mongoose');
const UserSchema = new Schema({
name: { type: String},
lastname: { type: String}
});
module.exports = UserSchema;
And then i create the connection with the model scooped to it.
databases/connection_1.js
const mongoose = require('mongoose');
const { Keys } = require('../keys');
const conn = mongoose.createConnection(
`mongodb://${Keys.DatabaseUser}:${Keys.DatabasePassword}#${Keys.DatabaseHost}/${Keys.DatabaseShema}`
, {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: true
});
conn.model('User', require('../models/user'), 'Users')
module.exports = conn;
But when i try to use my Schema to fetch the data of the Database i get next error:
UserSchema.find is not a function
routes/index.js
const app = require('express').Router();
const UserSchema = require('../models/user');
app.get('/index', async (req,res) => {
console.log(await UserSchema.find({name: 'Jhon Doe'}))
})
module.exports = app;

set database and collection using mongoose

How do I set my database and collection using mongoose ? I am trying to connect to a mongodb atlas database using mongoose. My database is called "test_db" and collection name is "users" where would I specify that information ?
This is my shema (data.js):
// /backend/data.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// this will be our data base's data structure
const DataSchema = new Schema(
{
_id: Number,
name: String,
password: String
}
);
// export the new Schema so we could modify it using Node.js
module.exports = mongoose.model("users", DataSchema);
and this is server.js:
const mongoose = require('mongoose');
const express = require('express');
var cors = require('cors');
const bodyParser = require('body-parser');
const logger = require('morgan');
const Data = require('./data');
const API_PORT = 3001;
const app = express();
app.use(cors());
const router = express.Router();
// this is our MongoDB database
const dbRoute = 'mongodb+srv://<user>:<password>#cluster0-bmihj.mongodb.net/test?retryWrites=true&w=majority';
;
// connects our back end code with the database
const conn = mongoose.connect(dbRoute, { useNewUrlParser: true });
//let db = mongoose.connection;
const db = conn.db('test_db');
var MyModel = mongoose.model('Test', new Schema({ name: String }));
db.once('open', () => console.log('connected to the database'));
// checks if connection with the database is successful
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
// this is our get method
// this method fetches all available data in our database
router.get('/getData', (req, res) => {
Data.find((err, data) => {
if (err) return res.json({ success: false, error: err });
return res.json({ success: true, data: data });
});
});
Through this line, you are connected to MongoDB:
const conn = mongoose.connect(dbRoute, { useNewUrlParser: true })
Consider:
dbRoute = mongodb://DB-username:DBpassword#ds245901.mlab.com:44422/Database-Name";
Here is your data information
DB-username = Your database user name
DBpassword = Your database password
Database-Name = Your database name (which database you want to use)
Therefore, no need to connect to your desired database like this:
const db = conn.db('test_db');

Mongoose models from two connections

I have the following setup:
/models/index.js
var glob = require('glob');
var mongoose = require('mongoose');
var Promise = require('bluebird');
mongoose.Promise = Promise;
mongoose.connect('mongodb://localhost/firstDB', {
useMongoClient: true
});
var models = glob.sync(__dirname + '/*.js', {ignore: '**/index.js'});
models.forEach(function (model) {
require(model);
});
/models/movie.js
var mongoose = require('mongoose');
var movieSchema = new mongoose.Schema({
title: String
}, {timestamps: true});
mongoose.model('movie', movieSchema);
/app.js
require('./models');
...
var Movie = mongoose.model('movie');
...
I would like to access secondDB models from the same app.js file, how can I do that?
Update: The end setup should look something like that:
(not sure how to pass the connection to the model)
/models/index.js
var glob = require('glob');
var mongoose = require('mongoose');
var Promise = require('bluebird');
mongoose.Promise = Promise;
var firstConnection = mongoose.connect('mongodb://localhost/firstDB', {
useMongoClient: true
});
var secondConnection = mongoose.connect('mongodb://localhost/secondDB', {
useMongoClient: true
});
var firstModels = glob.sync(__dirname + '/*.js', {ignore: '**/index.js'});
firstModels.forEach(function (model) {
require(model);
});
var secondModels = glob.sync(__dirname + '/second/*.js');
secondModels.forEach(function (model) {
require(model);
});
/models/movie.js
var mongoose = require('mongoose');
var movieSchema = new mongoose.Schema({
title: String
}, {timestamps: true});
mongoose.model('movie', movieSchema);
/models/second/car.js
var mongoose = require('mongoose');
var carSchema = new mongoose.Schema({
color: String
}, {timestamps: true});
mongoose.model('car', carSchema);
/app.js
require('./models');
...
var Movie = mongoose.model('movie');
var Car = mongoose.model('car');
...
Try this, Thanks!
var mongoose = require('mongoose')
var connection1 = mongoose.createConnection('connectionstring1');
var connection2 = mongoose.createConnection('connectionstring2');
Check this URL - http://mongoosejs.com/docs/connections.html
and Go to Multiple Connection Section.
Edit :
connectionOne.js
var mongoose = require('mongoose'),
mongoURI = 'mongodb://user:password#localhost:27017/dbOne';
module.exports = connectionOne = mongoose.createConnection(mongoURI);
connectionOne.on('connected', function() {
console.log('Mongoose connected to connectionOne');
});
require('./events')
connectionTwo.js
var mongoose = require('mongoose'),
mongoURI = 'mongodb://user:password#localhost:27017/dbTwo';
module.exports = connectionTwo = mongoose.createConnection(mongoURI);
connectionTwo.on('connected', function() {
console.log('Mongoose connected to connectionTwo');
});
require('./events')
events.js
var mongoose = require('mongoose'),
connectionOne = require('./connectionOne');
var Event = new mongoose.Schema({
name: { type: String, required: true },
date: { type: Date, required: false }
});
var connectionTwo = require('./connectionTwo');
var newEvent = new mongoose.Schema({
name: { type: String, required: true },
organizer: { type: String, required: true }
});
module.exports = {
connectionOne.model('Event1', Event);
connectionTwo.model('Event2', newEvent);
}
For more explanation - handling-multiple-databases-and-connections-with-mongoose
Note - I didn't test it.

foo.find(...).execFind is not a function - mongoose schema model

I have defined a custom type and I am trying to return all entries from mongo contained in the referenced collection:
Participant.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var participantSchema= new Schema({
email: String,
});
module.exports = mongoose.model('Participant', participantSchema, 'participants')
api.js
var express = require('express');
var router = express.Router();
var mongoose = require('mongoose');
var Participant = require('../models/Participant');
router.get('/all', function(req, res) {
var participant = mongoose.model('Participant');
//var participant = new Participant();
console.log(participant);
participant.find().execFind(function (arr,data) {
res.send(data);
});
});
module.exports = router;
But due something fishy, my model does not extend (I assume the default prototype)
participant.find(...).execFind is not a function
TypeError: participant.find(...).execFind is not a function
at /Users/bogdan/private/appName/routes/api.js:13:24
Any help is highly appreciated...
Thanks
execFind was replaced with exec back in one of the 3.x releases of Mongoose.
So you must now call exec instead of execFind.

Mongoose and Model Connections

I'm trying to get my head around how mongoose uses it's connection. At the moment I have:
// Datastore.js
var mongoose = require('mongoose'),
conn = mongoose.createConnection();
...
conn.open(host, database, port, options, callback); // Opens connection
// Model.js
var mongoose = require('mongoose');
var Schema = new mongoose.Schema({...})
module.exports = exports = mongoose.model('MyModel', Schema);
// Controller.js
var mongoose = require('mongoose');
var MyModel = mongoose.model('MyModel'); // Retrieves the model ok
MyModel.find({}, function(err, docs){
if(err){} //
console.log(docs); // Does not work
});
However this doesn't work... it only works if somehow I pass the connection across like so:
// Datastore.js
var mongoose = require('mongoose'),
conn = mongoose.createConnection();
...
conn.open(host, database, port, options, callback); //
mongoose.set('db', conn);
// Controller.js
var mongoose = require('mongoose'),
db = mongoose.get('db');
var MyModel = db.model('MyModel'); // Retrieve the model using the connection instance
MyModel.find({}, function(err, docs){
if(err){} //
console.log(docs); // Works
});
I think I'm approaching this in the wrong way... should the first approach work, and I'm doing something wrong?
It's easiest to just open the default connection pool that's shared by all your mongoose calls:
// Datastore.js
var mongoose = require('mongoose'),
db = mongoose.connect('localhost', 'dbname');
Then in all your other files access the pool using mongoose.model(...).
Looking at the docs it says:
var mongoose = require('mongoose');
var db = mongoose.createConnection('localhost', 'test');
Perhaps you need to put your connection details in for the create Connection
var mongoose = require('mongoose'),
conn = mongoose.createConnection('localhost', 'test');

Resources