best way to execute query in mongodb(3.0 drivers) and nodejs - node.js

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

Related

MongoDB collection error undefined

i am facing an issue while inserting data into collection.it gives an error of cannot read property of collection undefined. provide a solution of it i try my best.
here is my code.
var http = require('http');
var fs = require('fs');
var querystring = require('querystring');
var MongoClient = require('mongodb').MongoClient;
var url ="mongodb://127.0.0.1:27017/college";
var port = 4000;
http.createServer((req,res) => {
if(req.url==="/form")
{
res.writeHead(200,{"Content-Type": "text:html"});
fs.createReadStream("./public/form.html" , "UTF-8").pipe(res);
}
if(req.method==="POST")
{
var data = " ";
req.on("data", function(chunk)
{
data += chunk;
});
req.on("end" , function(chunk){
MongoClient.connect(url , function(err,db){
if(err) throw err;
var q = querystring.parse(data).
db.collection('res').insertOne(q,function(err,res){
if(err) throw err;
console.log("data is insert");
db.close();
});
})
});
}
}).listen(port);
console.log(port);
here is erro i am facing
Well I would suggest your to go this way.
1- Don't use database name in when creating mongodburl i-e
replace
var url ="mongodb://127.0.0.1:27017/college";
with
var url ="mongodb://127.0.0.1:27017/";
And now when you try to connect with mongodb server you'll get mongodb constructor in the callback function so you'll have to add one extra line of code. Something like below
MongoClient.connect(url, function (err, dbC) {
if (err) throw err;
var db = dbC.db("college");
var q = querystring.parse(data).
db.collection('res').insertOne(q, function (err, res) {
if (err) throw err;
console.log("data is insert");
db.close();
});
})
This way you'll get res collection defined for the database college (I am assuming you've already defined that collection in your database with some query like db.createCollection('res')) and then it should work
Thanks

ES6 : How to export this variable of node.js?

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);
});
}
}

How to check if db exists during mongodb connection using mongoose.connect?

I've tried to use mongoose.connect to check if a db exists,
mongoose.connect("mongodb://localhost:27017/notexistdb",function(err){
if(err) console.log(err);
});
The callback doesn't contain error message, so how can I determine whether the database exists or not.
You can easily find out by getting database list.
var mongoose = require('mongoose')
, Admin = mongoose.mongo.Admin;
/// create a connection to the DB
var connection = mongoose.createConnection(
'mongodb://user:pass#localhost:port/database');
connection.on('open', function() {
// connection established
new Admin(connection.db).listDatabases(function(err, result) {
console.log('listDatabases succeeded');
// database list stored in result.databases
var allDatabases = result.databases;
});
});
You could try using open and error events to see if you can connect to the database. If you can connect to it, then it exists. If you can't, then it doesn't.
var mongoose = require('mongoose');
mongoose.connection.on('open', function (ref) {
console.log('Connected to Mongo server...');
});
mongoose.connection.on('error', function (err) {
console.log('Could not connect to Mongo server...');
console.log(err);
});
mongoose.connect('mongodb://localhost:27017/notexistdb',function(err){
if(err) console.log(err);
});
If you want to get your answer returned, you need to use the desync library.
Install desync using npm i desync
You can also use the following function in a different file by exporting it.
const mongoose = require("mongoose");
var Admin = mongoose.mongo.Admin;
const deasync = require("deasync");
function checkDatabase (dbName) {
var check; // we will return this value
var uri = "mongodb://localhost:27017/";
// connect with mongoDB
mongoose.connect(uri, {useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true})
.then(() => {
new Admin(mongoose.connection.db).listDatabases((err, result) => {
var allDatabases = result.databases;
check = allDatabases.some((database) => database.name === dbName);
});
})
.catch((err) => {
console.log("some error occured");
});
// wait while mongoose executes the result
while (check == null) {
deasync.runLoopOnce();
}
return check; // either true or false
};
We need to use desync because much of the node's functionalities are asynchronous. To know more: Click Here - Callback Functions

get the last updated mongo id from nodejs

am working on push notifications using mongodb and nodejs.
I can see the newly added notifications (which are addede in Mongodb) in my browser
But, if I updated the record, the value is not updating in the browser
// if no error get reference to colelction named: 'notifications'
db.collection('notifications', function(err, collection){
if(err) {
throw err;
}
// if no error apply a find() and get reference to doc
collection.find().sort({
$natural: -1
}).limit(1).nextObject(function(err, doc) {
// Rewind the cursor, resetting it to point to the start of the query
if(err) {
throw err;
}
// using tailable cursor get reference to our very first doc
var query = {
_id: {
$gt: doc._id
}
};
var options = {
tailable: true,
awaitdata: true,
numberOfRetries: -1
};
var cursor = collection.find(query, options).sort({
$natural: 1
});
// This function will take cursor to next doc from current as soon as 'notifications' database is updated
function next() {
cursor.nextObject(function(err, message) {
if (err) throw err;
console.log(message.message);
mdsok.volatile.emit('notification', message);
next();
});
}
// what you need to do is: call it first time
next();
});
This is what i am doing in my code.
what should I do to update the value in the browser when I update the same in db.
Please help me . Thanks in advance!
My problem was solved upto some extent.
var http = require('http'),
fs = require('fs'),
// NEVER use a Sync function except at start-up!
index = fs.readFileSync('index.html');
// Send index.html to all requests
var app = http.createServer(function(req, res) {
res.writeHead(200, {
'Content-Type': 'text/html'
});
res.end(index);
});
// Socket.io server listens to our app
var io = require('socket.io').listen(app);
var MongoClient = require('mongodb').MongoClient;
function getdata(){
MongoClient.connect("mongodb://127.0.0.1:27017/test", function(err, db) {
var collection = db.collection('my_collection');
var stream = collection.find({
//'_id': new ObjectID('53eb6f2e75fd7ad00d000029')
//_id: ObjectID.createFromHexString("53eb6f2e75fd7ad00d000029")
}).stream();
stream.on("data", function(item) {
io.sockets.emit('db_status', {
status: item.status
});
prev = item.status;
console.log(prev);
});
stream.on("end", function() {
console.log("Done loading data");
});
});
}
// Send current time every 5 secs
setInterval(getdata, 5000);
// Emit welcome message on connection
io.sockets.on('connection', function(socket) {
socket.emit('welcome', {
message: 'Welcome!'
});
socket.on('i am client',function(data){
console.log(data);
});
});
app.listen(3000);
for every 5 secs, i am hitting the db and getting the value and displaying it in the browser.
To get the newly inserted object, we are using .nextObject() in node.js
Is there any way to get the updated object of the db as above in node.js.

Remove a MongoDB Document using Express JS

I have careted an application that interacts with MongoDb using NodeJS (Express JS). I am trying to remove a document using the "_id" (the one generated by MongoDB). The following piece of code just logs "Deleted Successfully", but does not actuall remove the record:
app.post('/TaskDone', function (req, res) {
var mongo = require('mongodb'),
Server = mongo.Server,
Db = mongo.Db;
var server = new Server('localhost', 27017, { auto_reconnect: true });
var database = new Db('pending-list-2', server);
database.open(function (err, db) {
if (!err) {
console.log("Connected for Deletion");
db.collection('tasks', function (err, coll) {
var str = "{_id :"+"ObjectId(" + "\"" + req.body + "\"" + ")" + "}";
console.log(str);
coll.remove(str, function (err) {
if (err) console.log(err);
else console.log("Deleted successfully");
}
);
});
}
});
});
If I use the MongoDB client and just run db.tasks.remove({_id:ObjectID("idhere")}) , it works. Is there something wrong with the express js code that I have written. I have tried a lot of things but nothing seems to work.
You must create an ObjectID from the mongodb library:
Also this is expected that you do not have any error. The remove() is executed, but the filter is probably invalid.
So you will have to write something like like:
var mongodb = require('mongodb');
...
...
collection.remove(
{_id: new mongodb.ObjectID( req.body) },
function (err, result){
//check result to see how many document are deleted
});
Try as below:
var id = {
_id: req.body.id
};
var collection = db.collection("tableName");
collection.remove(id, function(err, records){
if(err){
console.log("Error" + err);
}
else{
console.log("Omega Job Removed");
}
});

Resources