In node.js I am writing query to insert document to collection, but that query inserting only one document. Below the js code is,
app.js
router.post('/creatList', function(req,res){
console.log(req.body.email);
var emails = req.body.email;
if(req.body.wData.wishListType == 'Shared'){
var findUsers = function(db, callback) {
var cursor;
cursor = db.collection('users').find({email: { $in: emails }})
cursor.toArray(function(err, docs){
if(err){
callback(new Error("Some problem"));
} else {
callback(null,docs);
}
});
};
MongoClient.connect(config.database, function(err, db) {
assert.equal(null, err);
findUsers(db, function(err,docs) {
db.close();
console.log(docs);
var inserts_processing = 0;
for(var key in docs){
console.log(key);
var ids = docs[key]._id;
inserts_processing++;
console.log(ids);
var insertDocument = function(db, callback) {
db.collection('notifications').insertOne({
"userId" : ids,
},function(err, result) {
inserts_processing--;
assert.equal(err, null);
console.log("Inserted a document into the notifications collection.");
if(inserts_processing == 0){
db.close();
callback();
}
});
};
MongoClient.connect(config.database, function(err, db) {
assert.equal(null, err);
insertDocument(db, function() {
db.close();
});
});
}
});
});
} else {
console.log("other");
}
});
In the above code console.log contains two ids 570dec75cf30bf4c09679deb
56fe44836ce2226431f5388f but actually it inserting only last one.
According to your updated code I will try the following
router.post('/creatList', function(req,res){
console.log(req.body.email);
var emails = req.body.email;
if(req.body.wData.wishListType == 'Shared'){
// Open one connection to find users and insert documents
MongoClient.connect(config.database, function(err, db) {
assert.equal(null, err);
if(!err){
findUsers(db, function(err,docs) {
if(!err){
insertDocs(db, docs, function(){
db.close(); // Close connection
console.log("All documents have been inserted");
res.status(200).send("All is OK");
});
}
});
});
}
} else
console.log("other");
});
function insertDocs(db, docs, callback){
var inserts_processing = 0; // Will contain the number of inserts pending operation
for(var key in docs){
var ids = docs[key]._id;
inserts_processing++; // Before writing data, add one to processing inserts
db.collection('notifications').insertOne({
"userId" : ids,
}, function(err, result) {
inserts_processing--; // One insert have been finished, so remove one
assert.equal(err, null);
console.log("Document inserted into the notifications collection.");
// If all inserts have been finished, call back the function
if(inserts_processing == 0)
callback();
});
}
}
function findUsers(db, callback) {
var cursor;
cursor = db.collection('users').find({email: { $in: emails }})
cursor.toArray(function(err, docs){
if(err)
callback(new Error("Some problem"));
else
callback(null,docs);
});
};
Related
Im trying to connect to my Mongodb and insert some documents if they are not already in the db. It works fine with the first inserts but in the function existInDatabase it sometimes does not execute the callback function.
var MongoClient = require('mongodb').MongoClient;
var mongoData = require('./mongoData');
var exports = module.exports = {};
var dbName = 'checklist';
MongoClient.connect(mongoData.ConString, {
useNewUrlParser: true
}, function(err, db) {
if (err) throw err;
for (var key in mongoData.Customers) {
if (!existsInDatabase(mongoData.Customers[key], 'Customers')) {
db.db(dbName).collection('Customers').insertOne(mongoData.Customers[key], function(err, res) {
if (err) throw err;
console.log('1 document inserted');
db.close();
});
}
}
for (var key in mongoData.Categorys) {
if (!existsInDatabase(mongoData.Customers[key], 'Customers')) {
db.db(dbName).collection('Categorys').insertOne(mongoData.Categorys[key], function(err, res) {
if (err) throw err;
console.log('1 document inserted');
db.close();
});
}
}
});
function existsInDatabase(obj, collection) {
var result = false;
MongoClient.connect(mongoData.ConString, {
useNewUrlParser: true
}, function(err, db) {
db.db(dbName).collection(collection).find({}).forEach(function(doc) {
if (doc.id == obj.id) {
result = true;
}
}, function(err) {
console.log(err);
});
});
return result;
}
I have made a few changes to your code. It seems you are new to async programming, spend some time to understand the flow. Feel free for any further query. Here is your code.
// Welcome to aync programming
// Here no one waits for the slow processes
var MongoClient = require('mongodb').MongoClient;
var mongoData = require('./mongoData');
var exports = module.exports = {};
var dbName = 'checklist';
// Make the connection for once only
MongoClient.connect(mongoData.ConString, { useNewUrlParser: true },
function(err, db) {
if (err) throw err;
var myDB = db.db(dbName); // create DB for once
for (var key in mongoData.Customers) {
//make call to the function and wait for the response
existsInDatabase(mongoData.Customers[key], 'Customers', function(err, result) {
//once the response came excute the next step
if (result) {
myDB.collection('Customers').insertOne(mongoData.Customers[key], function(err, res) {
if (err) throw err;
console.log('1 document inserted');
});
}
});
}
for (var key in mongoData.Categorys) {
//make call to the function and wait for the response
existsInDatabase(mongoData.Customers[key], 'Customers', function(err, result) {
//once the response came excute the next step
if (result) {
myDB.collection('Categorys').insertOne(mongoData.Categorys[key], function(err, res) {
if (err) throw err;
console.log('1 document inserted');
});
}
});
}
// Both the for loop will work randomly without any order
function existsInDatabase(obj, collection, cb) {
var result = false;
myDB.collection(collection).findOne({ id: obj.id }, function(err, result)
{
if (err) {
//this cb will work only when db operation is complited
cb(err);
} else if (result) {
cb(null, true);
} else {
cb(null, false);
}
});
}
});
This code may result in some error. Feel free to ask more questions over it
db.db(dbName).collection(collection).find({}) returns a cursor per the docs. You are missing .toArray():
db.db(dbName).collection(collection).find({}).toArray()...
Before starting, please mind that i have been searching this over 2+ hours, the answer will be simple i know but i couldnt get it to work . i am new to express node mongodb,
MongoClient.connect(url, function(err, db) {
if (err) {
res.status(err.status); // or use err.statusCode instead
res.send(err.message);
}
var usernameGiven = req.body.usernameGiven;
//Select the database
var dbo = db.db("notifellow");
//run the query
var query = { username: usernameGiven , friends: []};
dbo.collection("users").findOne({ username: usernameGiven}, function(err, result) {
if (err){
res.status(err.status); // or use err.statusCode instead
res.send(err.message);
console.log("Query Error Occured!");
}
else {
if (result) {
//Send the response
res.send("EXISTS");
//I WOULD LIKE TO EXIT IF THIS LINE EXECUTES
}
}
});
dbo.collection("users").insertOne(query, function(err, result) {
if (err){
res.status(err.status); // or use err.statusCode instead
res.send(err.message);
console.log("Query Error Occured!");
}
else {
if (result) {
//Send the response
res.send("CREATED 201");
} else {
res.send("Failed to insert");
}
}
});
db.close();
});
my goal is to check if an user doesnt exists with given username, i would like to insert that to the DB.
i would like to exit if my query finds an match and arrange such that insertOne wont execute. please enlighten me!!
Once you are not using the async/await syntax you will have to nest the calls to MongoDB, so they execute in series. You can also use a module like async to achieve this.
MongoClient.connect(url, function(err, db) {
if (err) {
res.status(err.status); // or use err.statusCode instead
res.send(err.message);
}
var usernameGiven = req.body.usernameGiven;
//Select the database
var dbo = db.db("notifellow");
//run the query
var query = { username: usernameGiven , friends: []};
dbo.collection("users").findOne({ username: usernameGiven}, function(err, result) {
if (err){
res.status(err.status); // or use err.statusCode instead
db.close();
console.log("Query Error Occured!");
return res.send(err.message);
}
if (result) {
db.close();
return res.send("EXISTS");
}
dbo.collection("users").insertOne(query, function(err, result) {
if (err){
res.status(err.status); // or use err.statusCode instead
db.close();
console.log("Query Error Occured!");
return res.send(err.message);
}
db.close();
if (result) {
return res.send("CREATED 201");
}
res.send("Failed to insert");
});
});
});
Try this
dbo.collection("users").findOne({ username: usernameGiven}, function(err, result) {
if (err){
//put the error logic
}
else {
if (result) {
//Send the response
return result;
}
else{
// if above if block fails it means that user does not exist
//put the insert logic
}
});
So I am trying out my code for updating and showing it to the user. Basically it is able to do what I need to do but after performing it I get this error
C:\Users\tester01_2\myproject\node_modules\mongodb-core\lib\cursor.js:174
throw err;
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:357:11)
at ServerResponse.header (
C:\Users\tester01_2\myproject\node_modules\express\lib\response.js:725:10)
at ServerResponse.send
(C:\Users\tester01_2\myproject\node_modules\express\lib\response.js:170:12)
at C:\Users\tester01_2\myproject\dbUpdate.js:13:14
at C:\Users\tester01_2\myproject\dbUpdate.js:28:5
at handleCallback (C:\Users\tester01_2\myproject\node_modules\mongodb-
core\lib\cursor.js:171:5)
at nextFunction (C:\Users\tester01_2\myproject\node_modules\mongodb-
core\lib\cursor.js:682:5)
at Cursor.next [as _next]
(C:\Users\tester01_2\myproject\node_modules\mongodb-
core\lib\cursor.js:692:3)
at loop
(C:\Users\tester01_2\myproject\node_modules\mongodb\lib\cursor.js:694:8)
at _each
(C:\Users\tester01_2\myproject\node_modules\mongodb\lib\cursor.js:741:16)
This is my code
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var url = 'mongodb://localhost:27017/myproject';
module.exports = {
postCollection : function(req, res){
var issueQty = req.body.issueQty;
var itemDescrip = req.body.itemDescrip;
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
updateRecord(db, req, function(doc) {
return res.send('Record Found. Now updating this document...' +
itemDescrip + ' Record Updated. This is the new record ' + doc )
res.end();
db.close();
});
});
}
}
var updateRecord = function(db, req, callback) {
var cursor = db.collection('documents').find({'Item Description':
req.body.itemDescrip, 'Issued QTY': req.body.issueQty})
cursor.each(function(err,doc){
assert.equal(err, null);
if(doc != err){
console.log('Successfully queried');
console.log(doc);
callback(JSON.stringify(doc));
} else{
throw err;
}
});
db.collection('documents').updateMany(
{ 'Item Description': req.body.itemDescrip},
{
$set: { 'Issued QTY': req.body.issueQty }
},function(err, results) {
console.log(results);
console.log('Done');
console.log(results);
});
};
I think it has to do with my res due to all the threads I have seen being res being in a wrong position but I need to put my res.send there so that it can use doc. Is there any way to solve this problem? Thanks.
Firstly, you should remove return in front of res.send().
Secondly, in updateRecord function, the callback function shouldn't be called in a loop, it will execute multiple times. And you close the db before you execute updateMany.
If you want to send doc, you should use a temp array to hold the doc, and pass it to res when you finish all logics in updateRecord.
If I understand you correctly, following is my modification of your codes,
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/myproject';
var updateRecord = function(db, req, callback) {
db.collection('documents').updateMany({ 'Item Description': req.body.itemDescrip }, {
$set: { 'Issued QTY': req.body.issueQty }
}, function(err, results) {
if (err) return callback(err);
console.log('Done');
console.log(results);
var cursor = db.collection('documents').find({
'Item Description': req.body.itemDescrip,
'Issued QTY': req.body.issueQty
});
var temp = [];
cursor.each(function(err, doc) {
if (err) {
return callback(err);
}
console.log('Successfully queried');
console.log(doc);
temp.push(JSON.stringify(doc));
});
callback(null, temp);
});
};
module.exports = {
postCollection: function(req, res) {
var issueQty = req.body.issueQty;
var itemDescrip = req.body.itemDescrip;
MongoClient.connect(url, function(err, db) {
if(err) {
res.send(err);
res.end();
db.close();
return;
}
updateRecord(db, req, function(err, docs) {
if(err){
res.send(err);
}
else{
res.send(docs);
}
res.end();
db.close();
});
});
}
}
How to get last inserted id in node.js from mongodb.
My code is as follow:
var insertDocument = function(db, callback) {
db.collection('feedback_replies').insertOne( {
"feedback_id" : req.body.id,
"reply_text" : req.body.reply,
"replied_by" : "admin",
"replied_at" : new Date()
}, function(err, result) {
console.log("Record added as "+result);
assert.equal(err, null);
callback();
});
};
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
insertDocument(db, function() {
db.close();
});
});
I have created collection feedback_replies in which I insert. I want to get last inserted id from collection.
you can get the _id in the callback result as:
var insertDocument = function(db, callback) {
db.collection('feedback_replies').insertOne( {
"feedback_id" : req.body.id,
"reply_text" : req.body.reply,
"replied_by" : "admin",
"replied_at" : new Date()
}, function(err, result) {
console.log("Record added as "+result.insertedId);
assert.equal(err, null);
callback();
});
};
get full record what you have inserted as :
console.log("record inserted >>"+JSON.stringify(result.ops[0]));
router.get('/roomlist', function(req, res) {
var db = req.db;
var collection = db.get('roomlist');
collection.find(function(e,docs){
res.render('roomlist', {
"roomlist" : docs
});
});
});
The above controller is used to get list of rooms under a table "ROOMLIST". I need to get the details. I need to display all the roomname in the table ROOMLIST.
You should use find method of mongodb to get the documents from a collection. And then use cursor to iterate through the documents.
var getRoomlist = function(db, callback) {
var cursor =db.collection('roomlist').find( );
cursor.each(function(err, doc) {
assert.equal(err, null);
if (doc != null) {
return callback(false, doc);
} else {
return callback(true, null);
}
});
};
Then you can use your route /roomlist, to call the function getRoomlist when it gets hit and render the doc.
router.get('/roomlist', function(req, res){
programLogic(function(err, doc){
if(err){
console.log(err);
}
return res.send(doc);
});
});
If you still don't get it, just clone this and run through it
var programLogic = function (cb){
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
getRoomlist(db, function(err, doc) {
if(err){
console.log(err);
}
return cb(false, doc);
});
});
}// programLogic ends
var getRoomlist = function(db, callback) {
var cursor =db.collection('roomlist').find( );
cursor.each(function(err, doc) {
assert.equal(err, null);
if (doc != null) {
return callback(false, doc);
} else {
return callback(true, null);
}
});
};
router.get('/roomlist', function(req, res){
programLogic(function(err, doc){
if(err){
console.log(err);
}
return res.send(doc);
});
});
Which engine do you use for views rendering? Based on error message, property "roomname" has been interpreted as a partial, and cannot be found in views directory.