There is a piece of code that querying data from mongodb with node.js:
var MongoClient = require('mongodb').MongoClient
, assert = require('assert');
//a query that returns all the documents
var findDocuments = function(db, callback) {
// Get the documents collection
var collection = db.collection('documents');
// Find some documents
collection.find({}).toArray(function(err, docs) {
assert.equal(err, null);
console.log("Found the following records");
console.log(docs)
callback(docs);
});
}
var MongoClient = require('mongodb').MongoClient
, assert = require('assert');
// Connection URL
var url = 'mongodb://localhost:27017/myproject';
// Use connect method to connect to the server
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
console.log("Connected correctly to server");
var result = findDocuments(db, function() {
db.close();
});
});
//export the query result,but it doesn't work because it is a local variable in `MongoClient.connect()`
export {result}
Question:
I want to export the variable result, but it doesn't work because it is a local variable in MongoClient.connect().What should I do?
Define it outside the function like
var result
You need to define it globally in the document.
var MongoClient = require('mongodb').MongoClient
, assert = require('assert');
var result; //define it out here to be able to use it on anywhere
//a query that returns all the documents
var findDocuments = function(db, callback) {
// Get the documents collection
var collection = db.collection('documents');
// Find some documents
collection.find({}).toArray(function(err, docs) {
assert.equal(err, null);
console.log("Found the following records");
console.log(docs)
callback(docs);
});
}
var MongoClient = require('mongodb').MongoClient
, assert = require('assert');
// Connection URL
var url = 'mongodb://localhost:27017/myproject';
// Use connect method to connect to the server
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
console.log("Connected correctly to server");
result = findDocuments(db, function() { //give it its value
db.close();
});
});
//export the query result,but it doesn't work because it is a local variable in `MongoClient.connect()`
export {result}
If you are using ES6, I would recommend to use the keywords let/const instead of var.
Now about your issue why would you export result that way?
You should create a function connect() and export it. Then in your controller, call this function and handle whatever the outcome is.
Your connect here is totally asynchronous and uncontrolled, which is very bad behavior.
Exemple of what to do :
file mongodb.es6
export default class Mongodb {
connect() {
...
}
...
}
file main.es6
const mongodbObject = new Mongodb();
mongodbObject.connect()
.then(() => {
// I am connected so I can do whatever I want
})
.catch((err) => {
// I have an error and do something about it
});
Don't do it like this!
This will ONLY query the data when the file is being executed. I don't see any reason to do it this way.
Instead expose a function from this file, which will connect to the DB, query it and return the result object, everytime you call it.
export {
getResult: function(query, callback) {
// Connection URL
var url = 'mongodb://localhost:27017/myproject';
// Use connect method to connect to the server
MongoClient.connect(url, function(err, db) {
if (err) return callback(err);
console.log("Connected correctly to server");
result = findDocuments(db, function() {
db.close();
});
callback(null, result);
});
}
}
Related
I am currently trying to learn how to use MongoDB. I tried two similar but slightly different pieces of code and received completely different results. I am trying to understand why this happened.
CODE 1
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017';
MongoClient.connect(url, { useNewUrlParser: true }, function(err, client) {
if (err) throw err
var db = client.db('EmployeeDB')
var cursor = db.collection('Employee').find()
cursor.forEach(function(err, doc) {
console.log(doc);
console.log("Hello")
});
client.close()
});
CODE 2
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017';
MongoClient.connect(url, { useNewUrlParser: true }, function(err, client) {
if (err) throw err
var db = client.db('EmployeeDB')
var cursor = db.collection('Employee').find()
cursor.forEach(function(err, doc) {
if (err) {
console.log(err)
} else {
console.log(doc);
}
});
client.close()
});
Code 1 returned "undefined \n undefined \n undefined". However, Code 2 returned the actual objects and their information. I was wondering why only the second piece of code works correctly.
There is only one argument in the callback of cursor.forEach(), not two. Hence in both cases, "doc" is not defined, and only "err" is defined (which is the actual document).
Your code should thus be:
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017';
MongoClient.connect(url, { useNewUrlParser: true }, function(err, client) {
if (err) throw err;
var db = client.db('EmployeeDB');
var cursor = db.collection('Employee').find();
cursor.forEach(function(doc) {
console.log(doc);
});
client.close();
});
From MongoDB official docs:
The signature includes a single argument that is passed the current document to process.
Source: https://docs.mongodb.com/manual/reference/method/cursor.forEach/
db.js
var mongodb = require('mongodb').MongoClient;
var settings = require("./settings.js");
var ObjectId = require('mongodb').ObjectID;
var db = {
selectData: function(collection, query, callback, project = false) {
mongodb.connect(settings.db_url, function(err, client) {
var database = client.db(settings.db_name);
if (err) throw err;
if (project !== false) {
console.log("Project is not false");
console.log( project);
database.collection(collection).find(query, project).toArray(function(err, result) {
client.close();
if (err) throw err;
callback(result);
});
} else {
database.collection(collection).find(query).toArray(function(err, result) {
client.close();
if (err) throw err;
callback(result);
});
}
});
}
}
module.exports = db;
server.js
here is a simple query with single database call takes few seconds not a big deal but still not good method as per experts.
var db = require("db.js");
db.selectData("testCollection",{},function(data){
console.log(data);
});
Now here is a multi query nested database calls which takes more time and really bad for performance and speed
var db = require("db.js");
db.selectData("testCollection", {}, function(data) {
db.selectData("testCollection", {}, function(data) {
db.selectData("testCollection", {}, function(data) {
db.selectData("testCollection", {}, function(data) {
db.selectData("testCollection", {}, function(data) {
console.log(data);
});
});
});
});
});
What i want is open connection once and use db object outside without connecting again and again for each request or nested querys for fast response
i also know that with mongodb nodejs 2.3 drivers its possible and i have tested it perfectly working but i am looking for solution how to do same with mongodb nodejs 3.0 drivers
in short i am looking for a method where i can connect once and execute querys faster for chat and real time applications and performance optimizations
thank you.
Here i found a great working code with nodejs 3.0 Mongodb drivers
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
var express = require('express');
var app = express();
const url = 'mongodb://Your connection string';
const dbName = 'your database name';
MongoClient.connect(url, function(err, client) {
const db = client.db(dbName);
app.get("/", function(req, res) {
db.collection("somedata").find({}).toArray(function(err, result) {
if (err) throw err;
res.send(JSON.stringify(result));
});
});
app.listen(3000);
});
Instead of connecting again and again for each request connect at once and use it for best way if database connection is lost you can connect again but here you have to use some logic to make live that connection again and app routes too
this works for me i hope it will work for developers looking for answers of this question
I have set up node and mongodb and have imported some yelp data into mongo. When I query using the mongo shell, I can see there are documents and everything is fine. However I'm unable to pass them along by adding them to an array and returning that array. When I hit up localhost:3000/api/reviews, I get a blank page. My console does log everything though so the node driver for mongo is working in getting the documents. Any ideas? I feel like it has something to do with the asynchronous nature of node.
var express = require('express');
var router = express.Router();
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var url = 'mongodb://localhost:27017/YelpDB';
var getReviews = function(db, callback) {
var cursor = db.collection('reviews').find( );
//JSONArray jsonarray = new JSONArray();
var data = [];
cursor.each(function(err, doc) {
assert.equal(err, null);
if (doc != null) {
var jsonDoc = JSON.stringify(doc);
console.log(typeof jsonDoc);
data.push(jsonDoc);
} else {
callback();
}
});
return data;
};
router.get('/reviews/', function(req, res, next) {
//res.send('respond with a resource');
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
var data = getReviews(db, function() {
db.close();
});
res.json({"reviews": data});
});
});
Please try this one, you should return the data at the end of cursor.each in the callback function.
var getReviews = function(db, callback) {
var cursor = db.collection('reviews').find( );
var data = [];
cursor.each(function(err, doc) {
if (err)
callback(err);
if (doc) {
var jsonDoc = JSON.stringify(doc);
console.log(typeof jsonDoc);
data.push(jsonDoc);
} else {
// at the end of cursor, return the data through callback
callback(null, data);
}
});
};
router.get('/reviews/', function(req, res, next) {
//res.send('respond with a resource');
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
getReviews(db, function(err, data) {
if (err)
throw err;
// send the data in callback function
res.json({"reviews": data});
db.close();
});
});
});
Getting started with Node.
Put together a custom module, which parses an Excel file into a MongoDB:
exports.excelFileParser = function(fileName){
if(typeof require !== 'undefined') XLSX = require('xlsx');
var mongodb = require('mongodb');
var MongoClient = mongodb.MongoClient;
var url = 'mongodb://127.0.0.1:27017/my_database';
var workbook = XLSX.readFile('./uploads/' + fileName);
var worksheet = workbook.Sheets[workbook.SheetNames[0]];
var json_conversion = XLSX.utils.sheet_to_json(worksheet);
MongoClient.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
} else {
console.log('Connection established to', url);
db.open(function(err, client){
client.createCollection("test_collection", function(err, col) {
client.collection("test_collection", function(err, col) {
{
json_conversion.forEach(function(record) {
col.insert(record, function(err, result) {
if(err) {
console.log(err);
}
else {
}
});
})
}
});
});
});
console.log("finished");
db.close();
}
});
};
In my server.js I require this module as follows:
var excelFileParser = require("excel-file-parser");
At a certain point in my node app, I need to execute the functionality of this module, and pass it a file name to be parsed.
When I try it this way:
excelFileParser(file.fieldname);
I get
TypeError: object is not a function
exception.
What is the proper way to run my module from within server.js?
Lets look at your module:
exports.excelFileParser = function(fileName) {
...
}
When you call require('excel-file-parser') you basically get the exports object.
So to invoke the function you have created you need to call the function:
var myParser = require("excel-file-parser");
myParser.excelFileParser('filename');
function get_db_connection(database_name,collection_name){
var collection;
MongoClient = require('mongodb').MongoClient;
// Connect to the db
MongoClient.connect('mongodb://localhost:27017/'+database_name, function(err, db) {
if(!err) {
collection=db.collection(collection_name);
console.log(collection);
} else {
console.log(err);
}
});
return collection;
}
i am simply confused with how to pass parameter to callback..will be better if someone post help link..
You can't return from an asynchronous function, you need to use a callback.
function get_db_connection(database_name, collection_name, callback) {
var MongoClient = require('mongodb').MongoClient;
// Connect to the db
MongoClient.connect('mongodb://localhost:27017/' + database_name, function(err, db) {
if(err) {
return callback(err);
}
callback(null, db.collection(collection_name));
});
}
You'd then use it like
get_db_connection(database_name, collection_name, function(error, collection) {
//do something with collection
});