Hi I am new to MongoDB and NodeJs. I am using "mongojs" module to simple read the data from mongodb. The code goes as follows:
var dbname = 'XXXX';
var databaseUrl = 'mongodb://localhost:27017/'+dbname;
var collections = ['candidate','cities','states','countries'];
var mongojs = require('mongojs');
var db = mongojs(databaseUrl, collections);
db.candidate.findOne({fname:'XXX'},function(err,doc){
if(err){
console.log(err);
}
else{
console.log(doc);
}
});
db.close();
When I run them in the terminal I get this error:
{ name: 'MongoError',
message: 'server localhost:27017 sockets closed' }
Seems like the db.close() is getting executed before the data is fetched. How do we handle such kind of issues.
The above code is asynchronous. While the operation for db.candidate.findOne() is being carried out. The node does not wait for the process to complete and it starts executing another line. So simply putting, db.close() in the callback can solve this error.
var dbname = 'XXXX';
var databaseUrl = 'mongodb://localhost:27017/'+dbname;
var collections = ['candidate','cities','states','countries'];
var mongojs = require('mongojs');
var db = mongojs(databaseUrl, collections);
db.candidate.findOne({fname:'XXX'},function(err,doc){
if(err){
console.log(err);
}
else{
console.log(doc);
}
db.close();
});
I am also a novice in node. So yes, #blake could be correct about what he said, we may never want to close the db connection.
Related
this is my problem. now the code is below
var mongoClient = require('mongodb').MongoClient;
var db = 'mongodb://localhost:27017/lcl';
var insertData = function(db,callback){
var collection = db.collection('user');
var data = [{"name":"lcl","age":"23","sex":"男"},{"name":"王小猫","age":"22","sex":"女"}];
collection.insert(data,function(err,result){
if (err) {
console.log(err);
return;
};
callback(result);
})
}
mongoClient.connect(db,function(err,db){
console.log("连接成功");
insertData(db,function(result){
console.log(result);
db.close();
})
})
above is the code I have written.
Please help me find the solution.
Try something like this. Check your Db and collections name.
var mongoClient = require('mongodb').MongoClient;
var db_config = 'mongodb://localhost:27017/conapp';
var insertData = function(db_config,callback){
var collection = db_config.collection('users');
var data = [{'username':'ddaaaa'}];
collection.insert(data,function(err,result){
if (err) {
console.log(err);
return;
};
callback(result);
})
}
mongoClient.connect(db_config,function(err,db_config){
insertData(db_config,function(result){
console.log(result);
db_config.close();
})
})
From official documentation:
callback (function) – this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the initialized db object or null if an error occured.
Logically you have to check for an error existence first and only then perform some operations on db
I would like to connect to mongodb first, then run everything else in my application.
To do it I have to write something like:
MongoClient.connect("mongodb://localhost/test", function(err, connection) {
if (err) { console.error(err); }
db = connection;
var app = express();
// Include API V1
require("./apiv1.js")(app, db);
app.listen(3000, function(err) {
if (err) { console.error(err); } else { console.log("Started on *:3000"); }
});
});
This makes my app to be completely indented inside the .connect function... Which looks ugly and takes space while I work on my project.
I think the best solution would be have the MongoDB connection synchronous (even because witout the DB connection my app cannot work so why should I do something while it's connecting?) and then run the rest of my code.
How can I do?
You can't connect to MongoDB synchronously, but you may get rid of this ugly callback from your code.
The best way to do it is to adopt some wrapper around node-mongodb-native driver.
Take a look at the following modules.
mongojs
var mongojs = require('mongojs');
var db = mongojs('localhost/test');
var mycollection = db.collection('mycollection');
mongoskin
var mongo = require('mongoskin');
var db = mongo.db("mongodb://localhost:27017/test", {native_parser:true});
monk
var monk = require('monk');
var db = monk('localhost/test');
var users = db.get('users')
Of course, internally all of them are establishing MongoDB connection asynchronously.
Using the async library, you can aleve some of these issues.
For example in my server startup I do the following :
async.series([
function(callback){
// Initialize the mongodb connection and callback on completion in init.
db.init(function(){
callback();
});
},
function(callback){
// Listen on requests etc.
webServer.init(function(){
callback();
});
},
function(callback){
// Set up anything else that I need
callback();
}
]);
If you are using Node 6 and up versions, you can do something like this:
const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://localhost:27017/mydb';
let db = null;
getdb();
//your code
async function getdb() {
db = await MongoClient.connect(url);
}
Bring the mongodb library.
Declare the url constant .
Declare the variable db as null.
Call the getdb function.
Create the getdb function which has firt the async word
Assign to the db variable the result of the connection with the key word await.
You can do it with thunky, thunky executes an async function once and caches it, the subsequent calls are returned from the cache.
const MongoClient = require('mongodb').MongoClient;
const thunky = require('thunky');
var connect = thunky(function(cb){
let url = 'mongodb://localhost:27017/test';
MongoClient.connect(url, function(err, client){
console.log('connecting')
cb(err, client);
})
})
connect( (err, client) => {
console.log('connection 1')
})
connect( (err, client) => {
console.log('connection 2')
})
connect( (err, client) => {
console.log('connection 3')
console.log('closing')
client.close();
})
*Note: I am using latest 3.x mongodb driver
The following is the connection string and options i'm using from node.js to connect to mongodb. My web application keeps re-trying and never posts back if the mongodb server is down. Where do I set the connection timeout so I can say db server is down when it is? (The following code works perfectly when the mongo server is up).
(function(database) {
var mongodb = require("mongodb");
database.ObjectID = mongodb.ObjectID;
var mongoUrl = "mongodb://localhost:27017/mydb";
var dbconn = null;
database.getDBConn = function(next){
if(dbconn){ next(null, dbconn); return; } //already connected: return dbconn
mongodb.MongoClient.connect(mongoUrl,
{server: {socketOptions: {connectTimeoutMS: 500}}}, function(err, database){
if(err){ next(err, null); return; } //connection fail: return error
dbconn = {db: database,
movies: database.collection("movie") };
next(null, dbconn); //connection success: return dbconn
});
}
})(module.exports);
Looking at http://mongodb.github.io/node-mongodb-native/driver-articles/mongoclient.html I would say use
MongoClient.prototype.close
method to check if the connection is closed.If the connection is closed then emit a notification that the database server is down.
I have a syntax problem in a module, I fail to do the SQL query.
I initialize the module database in file.js, it responds with console.log 'Connected to the database', then sends the data to the module in Database.newData(data), when it enters in runQuery nothing happens, no errors or result, nothing!
I look in runQuery if this query was ok and if this, I think what happens is that there is an error in my logic of node, the idea is to connect to the database and use runQuery to run any query that you pass.
file.js
var DB = require('./modules/database');
var Database = new DB();
Database.newData(data);
database.js
var mysql = require('mysql'),
queries = require('./queries'),
connection;
var DB = function(){
var db_config = {
host: 'localhost',
user: 'diegoug',
password: 'qwertyuiop',
database: 'test'
};
connection = mysql.createConnection(db_config);
connection.connect(function(err) {
if(err) {
console.log('error when connecting to database:', err);
}
console.log('Connected to the database');
});
}
DB.prototype.runQuery = function(Query,Data,cb){
// Here not pass nothing
connection.query(
Query,
Data,
function(err, results){
debugger;
if (err)throw err;
cb(results);
}
);
// look here if the query was well written and if it is, what happens is that it's simply not running anything in the connection
}
DB.prototype.newData = function(data){
var Query = queries.SQLNEWDATA,
data = [data];
var res = this.runQuery(Query,data);
console.log(res);
}
module.exports = DB;
I'm a big Node.js and Mongo newbie, so please be gentle.
So here's my Node.js app:
var mongo = require('mongodb');
var Server = mongo.Server;
var Db = mongo.Db;
var server = new Server('hostname.mongolab.com', 666, {auto_reconnect : true}, {w:0, native_parser: false});
var db = new Db('dbName', server, {safe:true});
db.open(function(err, client) {
if(err) { return console.dir(err); }
client.authenticate('mongolabUser', 'mongolabUserPassword', function(authErr, success) {
if(authErr) { return console.dir(authErr); }
var stream = client.collection('myCollection').find({}).stream();
stream.on('data', function(item) {console.log("Do something with item"); });
stream.on('end', function() {console.log("Empty!");});
});
db.close();
});
Through prodigious use of debugger statements, I've come to the conclusion that the client.authenticate doesn't seem to be run. It looks like it's about to execute that line, but then just leapfrogs over it and goes straight to db.close().
But that's just the first of my problems. At some point prior, I was able to connect in to the database and authenticate, but my user was no retrieving anything in the find({}) command. I tried all sorts of ways, and streams are my latest attempt before deciding to give up on it for now.
Mongolab seems to be on v2.0.7, my mongo installation is v2.2.1. When I use the command line tool to log in as mongolabUser and execute a command like db.myCollection.find(), I get everything in my collection, so it can't be an issue with permissions.
Any advice/suggestions?
client.authenticate() is asynchronous, so the line that calls it starts the authentication, but doesn't wait for the server to respond before moving on to executing the next line, db.close(). So by the time the server responds the connection has been closed by the client.
Does moving the db.close() inside the event handler for stream.end help?
var mongo = require('mongodb');
var Server = mongo.Server;
var Db = mongo.Db;
var server = new Server('hostname.mongolab.com', 666, {auto_reconnect : true}, {w:0, native_parser: false});
var db = new Db('dbName', server, {safe:true});
db.open(function(err, client) {
if(err) { return console.dir(err); }
client.authenticate('mongolabUser', 'mongolabUserPassword', function(authErr, success) {
if(authErr) { return console.dir(authErr); }
var stream = client.collection('myCollection').find({}).stream();
stream.on('data', function(item) {console.log("Do something with item"); });
stream.on('end', function() {
console.log("Empty!");
db.close();
});
});
});