toArray undefined in NodeJS and MongoDB - node.js

I am trying to run an aggregation MongoDB and Nodejs, but I have some difficulties in running the project.
When I enter the following command in the MongoDB shell:
db.data.aggregate([{$match: {}},{$group: {'_id': '$State', 'total': {'$sum': 1}} }]).toArray()
then I am getting the expected output.
However, when I use the following little Nodejs program
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/weather', function(err, db) {
if(err) throw err;
console.log("Connected correctly to server");
var col=db.collection('data');
col.aggregate([{$match: {}},{$group: {'_id': '$State', 'total': {'$sum': 1}} }])
.toArray(function(err, result) {
if(err) throw err;
console.log(result);
});
db.close();
});
then I am getting the error message:
'TypeError: Cannot read property 'toArray' of undefined'
Could somebody please help me?
Many thanks in advance, Andi

As #ExplosionPills correctly pointed out, your code won't work as the logging is done asynchronously and after the connection is closed so you could try removing the db.close() line or create a function that makes use of a callback function to returns the aggregation results:
var aggregateStates = function(db, callback) {
db.collection('data').aggregate(
[
{ $group: { "_id": "$State", "total": { $sum: 1 } } }
]
).toArray(function(err, result) {
console.log(result);
callback(result);
});
};
Call the aggregateStates function:
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/weather', function(err, db) {
aggregateStates(db, function() {
db.close();
});
});

According to mongo-native driver doc, aggregate() returns null. Therefore, toArray() cannot be called from what it returns. However, aggregate() takes a callback which has the result of aggregate() if successful. So here is the revised code:
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect('mongodb://localhost:27017/weather', function(err, db) {
if(err) throw err;
console.log("Connected correctly to server");
var col=db.collection('data');
col.aggregate([
{$match: {}},
{$group: {'_id': '$State', 'total': {'$sum': 1}} }
], function(err, result) {
if(err) {
db.close();
throw err;
}
console.log(result);
db.close();
});
});

Related

Mongodb find not printing json data

In the code I am trying to find all documents with code UE19CS204.But in the console.log
a big message is printed not the JSON data.The findOne() is working but not find().
I don’t know what change to do to find all documents with code UE19CS204.
var MongoClient = require(‘mongodb’).MongoClient;
var url = “mongodb://localhost:27017/”;
MongoClient.connect(url, { useUnifiedTopology: true } ,function(err, db) {
if (err) throw err;
var dbo = db.db(“pes”);
dbo.collection(“course”).find({“code”:“UE19CS204”}, function(err, result) {
if (err) throw err;
console.log(result);
});
dbo.collection(“course”).findOne({code:“UE19CS204”}, function(err, result) {
if (err) throw err;
console.log(result);
db.close();
});
});
The method find() creates a cursor for a query that can be used to iterate over results from MongoDB, see here.
Use toArray(), you can finde the documentation here.
dbo.collection(“course”).find({“code”:“UE19CS204”}).toArray(function(err, docs) {
if (err) {
throw err;
}
console.log(docs);
})
Full example:
const MongoClient = require('mongodb').MongoClient;
// Connection URL
const url = 'mongodb://localhost:27017';
// Database Name
const dbName = 'pes';
// Collection Name
const collectionName = 'course';
// Filter
const filter = { 'code': 'UE19CS204' }
// Use connect method to connect to the server
MongoClient.connect(url, { useUnifiedTopology: true }, function(err, client) {
if (err) {
throw err;
}
client.db(dbName).collection(collectionName).find(filter).toArray(function(err, docs) {
if (err) {
throw err;
}
console.log(docs);
})
client.close();
});

Mongo db returning empty results

My code:
MongoClient.connect(gloabl_vars.db.mongo.url,function(err, db) {
if(err) { throw err; }
var dbo=db.db("profilemanager");
var mquery={_id:'123454'};
db.collection('userinfo').find(mquery,{'_id':0,'subscriptions':1}).toArray(function(err,result){
if(err) throw err;
console.log(result);
});
});
}
am able to get the result from Robo3T mongo client but same is returning null through nodejs.
Robo3T:
db.getCollection('userinfo').find({_id:'66613'},{'_id':0,'subscriptions':1});
You are searching a record by {_id:'66613'} in Robo3T but your sample is {_id:'123454'} in node.js. Also projection in node.js find is not in this way. Try below Snippet
MongoClient.connect(gloabl_vars.db.mongo.url,function(err, db) {
if(err) { throw err; }
var dbo=db.db("profilemanager");
var mquery={_id:'66613'};
db.collection('userinfo').find(mquery).project({'_id':0,'subscriptions':1}).toArray(function(err,result){
if(err) throw err;
console.log(result);
});
});
}

Node.js MongoDB Find with projection to exclude _id still returns it

Trying to follow the examples here to filter by using a projection to exclude _id. The _id still returns:
Code
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/db1";
MongoClient.connect(url, function (err, db) {
if (err) throw err;
var dbase = db.db("db1"); //here
dbase.collection("customers").find(
{},
{
_id: 0
}
).toArray(function(err, result) {
if (err) throw err;
console.log(result);
db.close();
});
});
Result still return as follows:
[ { _id: 5a2bb2d6ee48575cb54c4365,
name: 'John',
address: 'Highway 71' }, { _id: 5a2bb2d6ee48575cb54c436d,
name: 'Susan',
address: 'One way 98' }, .... { _id: 5a2bb2d6ee48575cb54c4371,
name: 'Chuck',
address: 'Main Road 989' }, { _id: 5a2bb2d6ee48575cb54c4372,
name: 'Viola',
address: 'Sideway 1633' } ]
Theoretically _id should not be part of what is returned. What is wrong here?
To limit the fields you have to use fields option( dont know about new updates):
dbase.collection("customers").find({}, {
fields: { _id: 0 }
}).toArray(function(err, result) {
if (err) throw err;
console.log(result);
db.close();
});
UPDATE:
For version > 3 you have to use projection option instead:
dbase.collection("customers").find({}, {
projection:{ _id: 0 }
}).toArray(function(err, result) {
if (err) throw err;
console.log(result);
db.close();
});
In version 3 of the MongoDB API, the fields option has been deprecated. You should now use the projection option instead.
For example:
dbase.collection('customers').find({}, {
projection: {
_id: 0
}
}).toArray(function (err, result) {
if (err) {
throw err
}
console.log(result)
db.close()
})
The full list of supported options can be found here: http://mongodb.github.io/node-mongodb-native/3.0/api/Collection.html#find
Starting in version 3.4, there is now an option for adding .project() outside of find().
Using ES8 async,await.
Ex:
async function connectDB(url) {
try {
const db = await MongoClient.connect(url);
const dbase = db.db("db1"); //here
const results = await dbase.collection("customers").find().project({_id:0}).toArray();
console.log(result);
db.close();
}
catch(err) {
throw err;
}
}
Docs here and another example here.

Unable to update the database using findAndModify

I'm using Node.js with mongodb.
var mongo = require("mongodb").MongoClient;
var url = process.env.MLAB_URI;
mongo.connect(url, function (err, db) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
} else {
//HURRAY!! We are connected. :)
console.log('Connection established');
var sequence = db.collection('sequence')
//Find and modify the sequence counter.
var obj = sequence.findAndModify({
query: {_id: 1},
update: { $inc: {seq: 1}},
new: true
});
console.log(obj);
sequence.find({_id:1}).toArray(function(err,res){
if(err)
console.log(err);
else
console.log(res)
});
db.close();
}
});
But the above code is not updating the database and the output of obj that is returned is Promise { <pending> } .
The complete output is
Connection established
Promise { <pending> }
[ { _id: 1, seq: 0 } ]
I need to update the value and retrieve the object . Is there any way to do that?
Thanks in advance!
Please change the findAndModify as mentioned below.
var obj = sequence.findAndModify(
{_id: 1},
{},
{ $inc: {"seq": 1}},
{new:true, upsert:true}
);
Second option to avoid promise:-
Comment the console.log(obj);
var obj = sequence.findAndModify(
{_id: "1"},
{},
{ $inc: {"seq": 1}},
{new:true, upsert:true}, function (err, doc) {
if(err)
console.log(err);
else
console.log(doc);
}
);
You are referring the Mongo shell version and try implementing the same using NodeJS version. The NodeJS findAndModify version is little different.
In order to get the old value of seq, you can set the new flag to false and doc.value.seq gives you the old value (i.e. value before update).
sequence.findAndModify(
{_id: "1"},
{},
{ $inc: {"seq": 1}},
{new:false, upsert:true}, function (err, doc) {
if(err)
console.log(err);
else {
console.log(doc);
console.log(doc.value.seq);
}
});
change to
var obj = sequence.findOneAndModify({
_id: 1,
update: { $inc: {seq: 1}},
upsert: true
});

Mongodb findone method does not work

function updateMongo(url, cached) {
console.log("Update mongo called");
MongoClient.connect('mongodb://127.0.0.1:27017/dbnerds', function(err, db) {
if(err) {
return console.log(err);
}
var cache = db.collection('cache');
cache.insert({url: url, image: null}, {safe: false}, null);
cache.findOne({ url: url }, function(err, result) {
console.log(result);
});
db.close();
});
};
As you can see from my code, that I insert url into mongodb, but when I do findOne operation, it seems it does not work. The console did not print out any result. What is wrong with here?
The problem is because there is no guarantee that the call to .insert() has finished when the call to .findOne() is executed.
Try using the following approach instead:
function updateMongo(url, cached) {
console.log("Update mongo called");
MongoClient.connect('mongodb://127.0.0.1:27017/dbnerds', function(err, db) {
if(err) {
return console.log(err);
}
var cache = db.collection('cache');
cache.insert({url: url, image: null}, {safe: false}, function(err, n) {
// Make the call to findOne until insert has finished
cache.findOne({ url: url }, function(err, result) {
console.log(result);
// close the DB after you are done
db.close();
});
});
});
};
Notice how I moved the call to findOne() to be the callback function executed after the insert has finished.

Resources