mongodb + node connection string - node.js

I'm having trouble connecting mongodb to my local machine. I'm new at this and can't seem to figure it out from the docs or other stackoverflow posts.
I have a database.js file, and I think my connection string is wrong:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost');
// I've tried this too:
// mongoose.connect('mongodb://localhost/test');
// mongoose.connect('mongodb://localhost:8080/test');
module.exports = {
'url' : 'mongodb://localhost:27017/test'
}
I've got mongod running in one tab and shows 4 connections open - I don't know if it's this or the connection string.
Then in a 2nd tab, I've connected to a db called "test".
Lastly there's a very simple view. When I navigate to localhost:8080 (where process.env.PORT || 8080 is pointing to in server.js), it doesn't connect.

Try this
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');//Here test is my database
var Cat = mongoose.model('Cat', { name: String });
var kitty = new Cat({ name: 'Zildjian' });
kitty.save(function (err) {
if (err) {
console.log(err);
} else {
console.log('meow');
}
});

Here is configuration file
{
"db": {
"connection": "mongodb://localhost",
"name": "testdb"
}
}
Here is usage in code:
var dbUrl = config.get('db:connection') + '/' + config.get('db:name');
var db = mongoose.connection;
mongoose.connect(dbUrl, function(err) {
//your stuff here
});
Hope, it helps.
P.S. Could you please provide how you catch no connection to db?

Related

Node.js and MongoAtlas - How can I connect to multiple databases in the same application?

I'm writing a Node.js cli in which I've to read from one Mongo Atlas DB and write to another Mongo Atlas DB. I'll be reading documents from one db and writing equivalent documents in the other db, one document at a time. I've two separate connection files like this:
ReadDB.js:
require('dotenv').config();
const mongoose = require('mongoose');
const read_db_url = process.env.READDB_URI;
const readDB = async () => {
try {
await mongoose.connect(read_db_url,
{
useNewUrlParser: true,
useUnifiedTopology: true,
dbName: "dbProd"
}
);
} catch (err) {
console.error(err);
}
}
module.exports = readDB
WriteDB.js:
require('dotenv').config();
const mongoose = require('mongoose');
const write_db_url = process.env.WRITEDB_URI;
const writeDB = async () => {
try {
await mongoose.connect(write_db_url,
{
useNewUrlParser: true,
useUnifiedTopology: true,
dbName: "dbQA"
}
);
} catch (err) {
console.error(err);
}
}
module.exports = writeDB
This what I've so far for the main application (cli.js):
cli.js:
require('dotenv').config();
const mongoose = require('mongoose');
const connectReadDB = require('./ReadDB.js');
const connectWriteDB = require('./WriteDB.js');
connectReadDB();
connectWriteDB();
const findProduct = async (productId) => {
products = await Products.find({_id:productId});
}
I guess my confusion is how Node.js will know which db to read from to begin with? Will I need separate set of models, one for read and one for write? How can I establish two simultaneous connections in the same Node.js app?
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:
const mongoose = require('mongoose')
const connection = mongoose.createConnection('mongodb://localhost/db1');
const connection2 = mongoose.createConnection('mongodb://localhost/db2');
const Schema = new mongoose.Schema({})
const model1 = connection.model('User', Schema);
const model2 = connection2.model('Item', Schema);
model1.find({}, function() {
console.log("this will print out last");
});
model2.find({}, function() {
console.log("this will print out first");
});

Best practice running queries in Node.js with MongoDB driver 3.6?

The official documentation of the Node.js Driver version 3.6 contains the following example for the .find() method:
const { MongoClient } = require("mongodb");
// Replace the uri string with your MongoDB deployment's connection string.
const uri = "mongodb+srv://<user>:<password>#<cluster-url>?w=majority";
const client = new MongoClient(uri);
async function run() {
try {
await client.connect();
const database = client.db("sample_mflix");
const collection = database.collection("movies");
// query for movies that have a runtime less than 15 minutes
const query = { runtime: { $lt: 15 } };
const options = {
// sort returned documents in ascending order by title (A->Z)
sort: { title: 1 },
// Include only the `title` and `imdb` fields in each returned document
projection: { _id: 0, title: 1, imdb: 1 },
};
const cursor = collection.find(query, options);
// print a message if no documents were found
if ((await cursor.count()) === 0) {
console.log("No documents found!");
}
await cursor.forEach(console.dir);
} finally {
await client.close();
}
}
To me this somewhat implies that I would have to create a new connection for each DB request I make.
Is this correct? If not, then what is the best practise to keep the connection alive for various routes?
You can use mongoose to set a connection with your database.
mongoose.connect('mongodb://localhost:27017/myapp', {useNewUrlParser: true});
then you need to define your models which you will use to communicate with your DB in your routes.
const MyModel = mongoose.model('Test', new Schema({ name: String }));
MyModel.findOne(function(error, result) { /* ... */ });
https://mongoosejs.com/docs/connections.html
It's 2022 and I stumbled upon your post because I've been running into the same issue. All the tutorials and guides I've found so far have setups that require reconnecting in order to do anything with the Database.
I found one solution from someone on github, that creates a class to create, save and check if a client connection exist. So, it only recreates a client connection if it doesn't already exist.
const MongoClient = require('mongodb').MongoClient
class MDB {
static async getClient() {
if (this.client) {
return this.client
}
this.client = await MongoClient.connect(this.url);
return this.client
}
}
MDB.url='<your_connection_url>'
app.get('/yourroute', async (req, res) => {
try {
const client = await MDB.getClient()
const db = client.db('your_db')
const collection = db.collection('your_collection');
const results = await collection.find({}).toArray();
res.json(results)
} catch (error) {
console.log('error:', error);
}
})

nodejs: does a find query to select n last records need to run asynchronously

I am a newbie in nodejs. I want to fetch n last records from mongo and write them to a socket when a(n android) client connects.
I wrote some code and it was okay when I tested it on a vps i had, but, after moving to new vps a problem appeared.
When the first client connects to the socket, it does not get the records. However, if a second client connects to the socket the find query runs again and the first client can see the related emit, but, not for second client!
I added a log after the io.emit command and it runs for every client connecting.
I also added another emit that just sends a test text and it delivered to client as soon as he connected.
My code:
const express = require('express'),
http = require('http'),
app = express(),
server = http.createServer(app),
io = require('socket.io').listen(server);
app.get('/', (req, res) => {
res.send('Chat Server is running on port ......')
});
var mongoose = require('mongoose');
var ChatMessage = require('./chatmessage');
var chatsdb = "mongodb://localhost:27017/chatsdb"
mongoose.connect(chatsdb, {useNewUrlParser: true});
mongoose.connection.on('connected', function () {
console.log('Mongoose connected!')
});
mongoose.connection.on('error', function (err) {
console.log('Mongoose default connection error:' + err);
});
io.on('connection', (socket) => {
let userId = socket.id;
console.log('user ' + userId + ' connected');//it always run
io.emit('connected_message', {"message_text": "ok!" , "user_id":userId});//it always run
ChatMessage.find().sort({created_at:-1}).limit(10).exec(function (err, posts) {
let list_of_messages = [];
for (let i = 0; i < posts.length; i++) {
if (posts[i] != null) {
let message = new ChatMessage({"message_text": posts[i].message_text, "name": posts[i].name , "created_at": posts[i].created_at});
list_of_messages.push(message);
}
}
io.emit('last_fifty_message', list_of_messages);
console.log("list_of_messages:" + list_of_messages); //it always run
});
});
server.listen(50000, () => {
console.log('Node app is running on port 50000')
});
and it's ChatMessage class:
var mongoose = require('mongoose');
const Schema = mongoose.Schema;
var ChatMessageSchema = new Schema({
name : { type: String, require:true },
message_text : { type: String , require:true },
created_at : { type:Date , default: Date.now },
message_id : { type: Number , autoIncrement:true }
});
ChatMessageSchema.pre('save',function(next){
this.created_at = new Date();
console.log('this.created_at : '+this.created_at)
next();
});
var ChatMessage = mongoose.model('ChatMessage' , ChatMessageSchema);
module.exports = ChatMessage;
I don't understand. If find records is a long process, how is it logged but not emitted and why is it emitted for clients that have connected already?
Does it need to run asynchronously? Can I use async/await or callbacks or ...??
You are using io.emit, io.emit is sending to all connected clients
For emitting only to the connected socket use socket.emit
By the way, you should check if error Isn’t null

Exporting mongoose connections to my model.js file

I just migrated from Mongoose 3 to 5.1.5 and have some issues. I have a nodejs application running trying to connect to multiple DBs on different hosts.
Connection.js file : This is used to maintain the connections.
I am exporting my connections to my models and binding the schemas
Connection.js file
const mongoose = require('mongoose');
const Mongoose = mongoose.Mongoose;
mongoose.Promise = require('bluebird');
-
-
const _connect = function (mongoUrl, options) {
mongoose.connect(mongoUrl, options).then(
() => { console.log('MongoDB Connected.'); },
err => { console.log('MongoDB not Connected.'); }
);
}
-
module.exports = {
conn1: new Connection('DB1'),
conn2: new Connection('DB2')
};
In model.js
I have created different models and each is saved as a different file.
const mongoose = require('mongoose');
const connections = require('./Connections');
-
-
const schema = new mongoose.Schema(model);
if (fileName.toLowerCase().includes('db2')) {
connections.conn2.model(fileName, schema);
} else {
connections.conn1.model(fileName, schema);
}
The whole setup was working properly in 3.x, but in 5.1.5, i get an issue
"connections.conn1.model is not a function"
To test the whole scenario, I commented one connection and gave my exports as below in Connection.js:
module.exports = {
mongoose: new Connection('DB1'),
};
and in model.js I just had
mongoose.model(fileName, schema);
which works perfectly. Please let me know what am I doing wrong.

How to connect openshift Phpmyadmin database using Nodejs Server?

How to connect "openshift phpmyadmin database" using nodejs server
Below is my code ... I am not getting result from the database ...
log :
Success{"fieldCount":0,"affectedRows":0,"insertId":0,"serverStatus":2,"warningCo
unt":0,"message":"","protocol41":true,"changedRows":0}
var connection = mysql.createConnection({
OPENSHIFT_NAMMAOORU_DB_HOST :'127.4.188.2',
OPENSHIFT_NAMMAOORU_DB_PORT :'3306',
OPENSHIFT_NAMMAOORU_DB_USERNAME:'adminfxxxxx',
OPENSHIFT_NAMMAOORU_DB_PASSWORD:'xxxxxxxxx',
OPENSHIFT_NAMMAOORU_DB_URL:'mysql://adminxxxx:xxxxxxx#127.4.188.2:3306',
//database:'nammaooru'
});
connection.connect(function(err,success){
if (err) {
throw err;
console.log("Error"+JSON.strinerr);
}
else
{
console.log("Success"+JSON.stringify(success));
}
});
app.get('/city',function(req,res){
try{
//var id = req.query.id;
/*var t=req.query.id;
console.log(t);
*/ /* var data = {
"error":1,
"Books":""
};*/
console.log(req.params.cityid);
var t=1;
connection.query("SELECT * from city",function(err, rows, fields){
console.log("success"+JSON.stringify(rows));
//console.log("success"+JSON.stringify(fields));
//console.log(JSON.stringify(rows));
res.send(JSON.stringify(err));
//console.log("success"+JSON.stringify(err));
});
}
catch(e)
{
console.log(e);
}
});
Local Rest url http://localhost:8000/city
{ code: "ER_NO_DB_ERROR", errno: 1046, sqlState: "3D000", index: 0 }
I don't think you are creating the mysql connection properly:
var connection = mysql.createConnection({
host: '127.4.188.2',
user: 'adminfxxxxx'',
password: 'xxxxxxxxx',
port: 3306
});
Try this just add database name as below
var connection = mysql.createConnection({
host :'127.4.188.2',
port :'3306', // if this doesn't work try removing port once
user:'adminfxxxxx',
password:'xxxxxxxxx',
database:'xxxxxxxxx', //specify database Name

Resources