How to modulize my mongoose setup - node.js

This use of db.model('Model_Name').find(...) worked before, but I've since split my database, model and controllers up, so now it seems I need to change things around Please help show where I'm going wrong:
schema.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var UsersSchema = new Schema({
display_name : String,
email : String
});
var ClientErrorsSchema = new Schema({
datetime : Number,
msg : String,
url : String,
line : Number
});
var users = mongoose.model('Users',UsersSchema);
var client_errors = mongoose.model('Client_Errors',ClientErrorsSchema);
module.exports = mongoose.model;
db.js
var mongoose = require('mongoose');
var model = require("./schema.js");
var MONGO = {
username: "admin",
password: "***",
server: 'localhost',
port: '*****',
db: 'db_name',
connectionString: function(){
return 'mongodb://'+this.username+':'+this.password+'#'+this.server+'/'+this.db;
},
options: {
server:{
auto_reconnect: true,
poolSize: 20,
socketOptions:{
keepAlive: 1
}
},
db: {
numberOfRetries: 10,
retryMiliSeconds: 1000
}
}
};
var db = mongoose.createConnection(MONGO.connectionString(), MONGO.options);
db.model = model;
db.on('error', function(err) {
f.consoleLogger("DB connection Error: "+err);
});
db.on('open', function() {
f.consoleLogger("DB connected");
});
db.on('close', function(str) {
f.consoleLogger("DB disconnected: "+str);
});
module.exports = db;
user.js
var db = require("./db.js");
...
db.model('Users').find(...)
So using the util.inspect, I can see the db has all of the models, but the error I'm getting on the find is TypeError: Cannot read property 'User' of undefined'.
UPDATE
Toad22222 provided great advice, and the schema appears to be valid - but the queries are not working - neither db.model.Users.find({...},function(err,data){...}); or db.model.Users.find({...}).exec(function(err,data){...}); fires the callback. I have put the same code in the on('open') event as well, nothing happens. Hopefully someone can explain why.
All advice appreciated!

Try out
module.exports = {
User: users,
ClientErrors: client_errors
}
instead of
module.exports = mongoose.model;
You want to be exporting the schemas you are creating, not the mongoose.model datatype.

Related

Set unique key in mongoose

I'm currently using the following code. I'm basically using the example from the mongoose documentation but I'm trying to get the name field to be unique
here I am intentionally creating two unique "kittens" and trying to save both of them
const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/test", {
useNewUrlParser: true,
useUnifiedTopology: true,
useCreateIndex: true
});
const db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error:"));
db.once("open", function () {
console.log("Connected to database");
});
const kittySchema = new mongoose.Schema({
name: { type: String, unique: true },
});
kittySchema.methods.speak = function () {
const greeting = this.name
? "Meow name is " + this.name
: "I don't have a name";
console.log(greeting);
};
const Kitten = mongoose.model("Kitten", kittySchema);
const fluffy = new Kitten({ name: "fluffy" });
fluffy.save();
const fluffy2 = new Kitten({ name: "fluffy" });
fluffy2.save();
Using the unique property doesn't seem to work because I keep getting duplicate entries in the database. I've also tried using the removedups key in the schema which I believe has been deprecated.
This property unique is not for data to be saved uniquely. It's for unique indexing that will be applied on field.
You can chech documentation here.
https://joshtronic.com/2018/06/07/unique-indexes-with-mongodb-and-mongoose/

I was writing code for database through mongoose but I am getting this error on the terminal mongoose.connection.on error

I am getting this error every time I start the app.....error is in the screenshots. Please let me know how to fix this up.Thanks in advance.enter image description here
enter image description here
You got error because Mongoose.connection is not yet exists when you try to access it. You need either use callback as
const Mongoose=require("mongoose").connect(config.dbURL,(error)=>{
if (!error) {
Moongose.connection.on("error",(error)=>{...your code here ..});
}
})
or use Promise
const Mongoose=require("mongoose").connect(config.dbURL)
.then(()=>{
Moongose.connection.on("error",(error)=>{...your code here ..});
});
You should definitely use some variables/identifiers to store the connection as explained in the Mongoose documentation here.
console.log your config and check whether they are being properly fetched.
The community also helps better if you provide more details and use code snippets instead of screenshots.
Next, check if your Database URL starts with mongodb://.
And then, you have a spelling error on line 19 where you define schema charUser but are trying to model chatUser on line 27.
Try putting Mongoose.promise = Promise; just after you import mongoose.
Also, I'd suggest you to use the following style:
1. Create db.js which will export the database connection for you.
const mongoose = require('mongoose');
mongoose.Promise = Promise;
const options = {
poolSize: 25,
socketTimeoutMS: 0,
keepAlive: true,
reconnectTries: 30,
user: 'MONGODB_USER',
pass: 'MONGODB_PASS',
auth: {
authdb: 'MONGODB_AUTH_DB',
},
};
const dbname = 'db_name_goes_here';
const host = 'db_server_URI_goes_here';
const port = port_number_goes_here || 27017;
const uri = `mongodb://${host}:${port}/${dbname}`; // a template string
const db = mongoose.createConnection(uri, options);
module.exports = db;
2. Use the connection in the Model file in this manner:
const { Schema } = require('mongoose');
const db = require('./db.js');
const chatUser = new Schema({
profileID: String,
fullName: String,
profilePic: String
});
const userModel = db.model('chatUser', chatUser);
module.exports = { userModel };
Try this:-
const MongoClient = require('mongodb').MongoClient;
// Connection URL
const url = 'mongodb://localhost:27017';
// Database Name
const dbName = 'test';
// Use connect method to connect to the server
MongoClient.connect(url, function(err, client) {
assert.equal(null, err);
console.log("Connected successfully to server");
const db = client.db(dbName);
});

How to interact with two mongodb server (mongoose) on one node server

I am using Mongoose. I have two Mongo DB Server i.e
Primary(27017, 27018, 27020 {replica set enabled on primary}) & Secondary(27021)
Now I want to interact with these two server through API in nodejs. Lets say
router.post('/connectToDB1', function (req, res) {
//Some logic for interacting with DB 1
})
router.post('/connectToDB2', function (req, res) {
//Some logic for interacting with DB 2
})
On my node server what I implemented is like this:
//On my app.js File
var Mongoose = require('mongoose').Mongoose;
Mongoose.Promise = global.Promise;
var Message = require('./models/message');
var mydb1;
var mydb2;
var instance1 = new Mongoose();
var uri1 = 'mongodb://127.0.0.1:27017, 127.0.0.1:27018, 127.0.0.1:27020/myDBName?replicaSet=newRep';
instance1.connect(uri1, { useMongoClient: true }).openUri(uri1, function (errr,db) {
if (errr) {
throw errr;
} else {
console.log("Primary Connection Successfull");
mydb1 = instance1;
}
});
var instance2 = new Mongoose();
var uri2 = 'mongodb://127.0.0.1:27021/secondary';
instance2.connect(uri2, { useMongoClient: true }).openUri(uri2 , function (errr,db) {
if (errr) {
throw errr;
} else {
console.log("Secondary Connection Successfull");
mydb2 = instance2;
}
});
Now I don't Know how to Interact/create A Query...
Any help is really Apreciated.
Mongoose has a function called createConnection() that returns a connection object. You can create multiple connections to different servers/replicaSets and create models specific to each connection. Here is an example:
49790706.js
#!/usr/bin/env node
'use strict';
const mongoose = require('mongoose');
const conn1 = mongoose.createConnection('mongodb://localhost:27017/test1');
const conn2 = mongoose.createConnection('mongodb://localhost:27018/test2');
const Schema = mongoose.Schema;
const userSchema = new Schema({
name: String
});
const adminSchema = new Schema({
name: String
});
const User = conn1.model('User', userSchema);
const Admin = conn2.model('Admin', adminSchema);
const billy = new User({ name: 'Billy' });
const root = new Admin({ name: 'root' });
async function run () {
await conn1.dropDatabase();
await conn2.dropDatabase();
await billy.save();
await root.save();
let b = await User.find({});
let r = await Admin.find({});
console.log('users:', b);
console.log('admins:', r);
return mongoose.disconnect();
}
run();
shell output
stack: ./49790706.js
users: [ { _id: 5acf1b72bb7d5f546c1a526f, name: 'Billy', __v: 0 } ]
admins: [ { _id: 5acf1b72bb7d5f546c1a5270, name: 'root', __v: 0 } ]
stack:
You need to be sure that when you create your models you attach them to the specific relevant connection, ie conn1.model(..). Also, when your app is ready to close the connections rather than call .close() on each one, note that you can call mongoose.disconnect() and it will close all connections in parallel.

Async.each not working with post to database [duplicate]

var mongo = require('mongoose');
var connection = mongo.createConnection('mongodb://127.0.0.1/test');
connection.on("error", function(errorObject){
console.log(errorObject);
console.log('ONERROR');
});
var Schema = mongo.Schema;
var BookSchema = new Schema({ title : {type : String, index : {unique : true}}});
var BookModel = mongo.model('abook', BookSchema);
var b = new BookModel({title : 'aaaaaa'});
b.save( function(e){
if(e){
console.log('error')
}else{
console.log('no error')
}});
Neither the 'error', or 'no error' are printed to the terminal. What's more the connection.on 'error' doesn't seem to fire either. I have confirmed that MongoDb is running.
this is a case where you are adding the model to the global mongoose object but opening a separate connection mongo.createConnection() that the models are not part of. Since the model has no connection it cannot save to the db.
this is solved either by connecting to mongo on the global mongoose connection:
var connection = mongo.createConnection('mongodb://127.0.0.1/test');
// becomes
var connection = mongo.connect('mongodb://127.0.0.1/test');
or by adding your models to your separate connection:
var BookModel = mongo.model('abook', BookSchema);
// becomes
var BookModel = connection.model('abook', BookSchema);
I really like Aaron's answer, and thanks to him I am now on my way to fixing the issue... although I'm not there yet! Here is my particular issue:
I want to have my schema and models defined in separate files, so I can reuse them from project to project. So as an example I have a file named W8DBItem.js as follows:
var mongoose = require('mongoose');
var itemSchema = new mongoose.Schema({ name: {type: String, required: true}});
module.exports = mongoose.model('W8DBItem', itemSchema);
In my program file I do this this:
var mongoose = require('mongoose');
var W8DBItem = require('../w8/W8DBItem.js');
var dbURL ='mongodb://localhost:27017/default';
var mongoOptions = { useNewUrlParser: true, bufferCommands: false }
mongoose.connect(dbURL, mongoOptions);
var db = mongoose.connection;
// DEAL WITH CONNECTION ERROR
db.on('error', console.error.bind(console, 'connection error:'));
// PREP DATA
var aWeight = { name: "My Test Name" };
var newWeightItem = W8DBItem(aWeight);
// CONNECTION ESTABLISHED
db.once('open', function() {
console.log("Here 1")
// TRY TO SAVE
newWeightItem.save(function (err, newWeightItem) {
if (err) {
console.log("Here 2");
console.log(err);
}
else {
console.log("Here 3");
console.log(newWeightItem);
}
});
});
When I run this program I get "Here 1" but never "Here 2" or "Here 3" in the console.
From Aaron's post I get that the W8DBItem object has no associated (and open) connections, but I am not sure how to go about fixing things. I could connect to the DB in the W8DBItem.js file, but I really don't like hard-coding the server info with the objects - I want these objects to be used in different files, and perhaps with different servers.
Ideas and suggestions are much appreciated!
[EDIT: SOLUTION FOUND!!!]
Instead of exporting my mongoose.model from my object file, I am only exporting the schema:
var mongoose = require('mongoose');
var itemSchema = new mongoose.Schema({name: {type: String, required: true}});
module.exports = itemSchema;
In my program files I then do this:
var itemSchema = require('../w8/W8DBItemSchema.js');
...
var W8DBItem = db.model('W8DBItem', itemSchema);
var newWeightItem = W8DBItem(aWeight);
...
Works like a charm. I hope this helps someone!
The posted answer does not solve the problem. Unfortunately, I cannot just upgrade my database, so that is not a solution either for me. But here I found a solution to this problem: https://github.com/Automattic/mongoose/issues/4064
Just use .$__save instead of .save as shown:
var b = new BookModel({title : 'aaaaaa'});
b.$__save({}, function(e){
if(e){
console.log('error')
// callback will show if e exists
}else{
console.log('no error')
// callback will show 'no error'
}});

I am getting an error of mongoose is not defined

I am creating an api using MongoDB, I am using Mongoose to create Data Persistence. However I am getting an error that Mongoose is not defined, I have used require function to call the node module but it is still giving me the same error.
Below is the connection file
var mongoose = require('mongoose')
var database = 'api'
const server = 'mongodb://localhost:27017/'+database
console.log(server)
mongoose.connect(server)
const db = mongoose.connection
console.log(db)
var Schema = mongoose.Schema
var ObjectId = Schema.ObjectId
const WeatherSchema = new Schema({
id: {type: String, required: true},
name: { type: String, required: true },
items: {type: String, required: true}
})
var WeatherDB = mongoose.model('DBlist', WeatherSchema)
You should wait for the database to connect, as it doesn't happen immediately. Something like this:
var mongoose = require('mongoose');
mongoose.connect(sever);
var db = mongoose.connection;
db.on('disconnect', connect); // auto reconnecting
db.on('error', function(err) {
debug('connection error:', err);
});
db.once('open', function (callback) {
// we're in the game, start using your Schema
const WeatherSchema = new Schema({...
});
p.s.
I've added little extra sugar just to let you know these events exist and are quite helpful to understand what's going on.

Resources