How to get number of documents by using find method express js? - node.js

How to get number of documents find total express js? I have searched in google and StackOverflow. But I could not find. what people saying is use countDocuments to get number of documents of the Model like following:
UserModel.countDocuments(function(err,count){
count
res.render('index',{count:count}); // returning count and rendering to index.ejs
});
But I want both resultset and at the same time recordcount like following
UserModel.find(function(err,data){
res.render('index',{data:data,count:data.count});
});

UserModel.find({}, null, options).exec().then(data => {
UserModel.count({}, (err, counts) => {
if (err) {
res.send(err)
} else {
res.render('index',{data:data,count:data.counts});
}
})
}).catch(err => {
res.send(err)
});

Since UserModel.find() returns an array, you can just return the count from data.length.
Also, just note that Model.count() has been deprecated in the latest mongoose version (v5.7.6). If you are adamant on using it or something similar, you can use one of the following:
Model.estimatedDocumentCount() (fast): which uses the collection's metadata to give you an estimate of the number of documents, see docs.
Model.countDocuments() (can be slow for large collections): for a more accurate count. see docs.

UserModel.find() returns an array, so you can just go ahead and run: res.render('index',{data:data,count:data.length});

Related

MongoDB and Node.js aggregate using $sample isn't returning a document

I'm new to Nodejs and mongoDB and I'm trying to get an aggregate function running that will select a random document from the database and return it. I've looked all over on the internet to figure out what I'm doing wrong and from what I can see my code looks like it should. For some reason however, when I try printing the result to console, it gives me an aggregation cursor object and I can't find the document I want anywhere within it. Here is my code for the aggregate function.
//get a random question
route.get('/question/random', function (req, res) {
database.collection('questions').aggregate(
[ { $sample: { size: 1} } ],
function(err, result) {
console.log(result);
})
})
It's because aggregation method returns AggregationCursor that won't return any documents unless you iterate through it.
For a simple iteration, you can do:
database.collection('questions').aggregate([{$sample: {size: 1}}]).forEach(console.log);
The forEach() method on the cursor will iterate it, and in this example will print it to the console.

How to get data and count in one query in mongoose

I tried to get notification as well as the data in one query and i tried like below but this is giving only count,
Categories.find(item).count().exec(function (err, result) {}
Can anyone please suggest help.
You can't get your data like this way as #adeneo said in the comment.
Use find to get all records and then check length of records
Categories.find({query},function (err, result) {
if(!err){
if(Array.isArray(result))
var count=result.length;
}
});
You can use #abdulbarik method if you want to fetch all the records.
If you are using a limit on the amount of data you need and you want the full count you can do the following:
Categories.count(query, function (err, count) {
Categories.find(query)
.limit(limit)
.toArray(cb);
});

How is insertMany different to collection.insert in Mongoose?

I scouted around to find the right solution for inserting a large amount of documents to MongoDB using Mongoose.
My current solution looks like this:
MongoClient.saveData = function(RecordModel, data, priority, SCHID, callback){
var dataParsed = parseDataToFitSchema(data, priority, SCHID);
console.log("Model created. Inserting in batches.");
RecordModel.insertMany(dataParsed)
.then(function(mongooseDocuments) {
console.log("Insertion was successful.");
})
.catch(function(err) {
callback("Error while inserting data to DB: "+err);
return;
})
.done(function() {
callback(null);
return;
});
}
But it appears to me there are other offered solutions out there. Like this one:
http://www.unknownerror.org/opensource/Automattic/mongoose/q/stackoverflow/16726330/mongoose-mongodb-batch-insert
Using collection.insert. How is that different to the Model.insertMany?
Same goes for update, my previous question: What is the right approach to update many records in MongoDB using Mongoose
Asks how do I update big chunk of data with Mongoose, defined by _id. The answer suggests to use collection.bulkWrite while I am under impression Model.insertMany can do it too.

Mongoose Find and Remove

I'm trying to delete multiple documents that satisfy a query. However I need the data of those documents for storing them in a separate collection for undo functionality. The only way I got this to work is with multiple queries:
Data.find(query).exec(function(err, data)
{
Data.remove(query).exec(function(err2)
{
ActionCtrl.saveRemove(data);
});
});
Is there a better way? In this post: How do I remove documents using Node.js Mongoose? it was suggested to use find().remove().exec():
Data.find(query).remove().exec(function(err, data)
{
ActionCtrl.saveRemove(data);
});
However data is usually 1, don't ask me why. Can I do this without infinitely nesting my queries? Thanks!
As you have noted, using the following will not return the document:
Data.find(query).remove().exec(function(err, data) {
// data will equal the number of docs removed, not the document itself
}
As such, you can't save the document in ActionCtrl using this approach.
You can achieve the same result using your original approach, or use some form of iteration. A control flow library like async might come in handy to handle the async calls. It won't reduce your code, but will reduce the queries. See example:
Data.find(query, function(err, data) {
async.each(data, function(dataItem, callback) {
dataItem.remove(function(err, result) {
ActionCtrl.saveRemove(result, callback);
});
});
});
This answer assumes that the ActionCtrl.saveRemove() implementation can take an individual doc as a parameter, and can execute the callback from the async.each loop. async.each requires a callback to be run without arguments at the end of each iteration, so you would ideally run this at the end of .saveRemove()
Note that the remove method on an individual document will actually return the document that has been removed.

"not contains" query in SailsJS Waterline

How can I create the not contains query that returns true if the item does not contain a certain value. I'm running mongoDB if it is relevant.
I can use the contains successfully however receive an error when I introduce the not. I've tried it with find and where but get the same regex error both times. I can add the exact error if its relevant.
Working version:
model.find({attribute: {'contains': value}})
.exec(function(err, users) {
// happy code
});
The following complains about some regex error:
model.find({attribute: {not: {'contains': value}}})
.exec(function(err, users) {
// sad code
});
There was an issue raised and closed in 2013 about this. Maybe something changed recently?
https://github.com/balderdashy/waterline/issues/22
Alexei, I don't think this is supported by waterline currently. There is a related issue which is marked as feature and that you can track:
https://github.com/balderdashy/waterline/issues/666
So far, you can only use native feature of Mongodb I think.
Model.native(function(err, collection) {
collection.find({
"attribute" : {
$ne : value, //Not Equal
//OR
$nin : [value1, value2]// Not In
}
}).toArray(function(err, docs) {
if (err) return callback(err, docs);
res.json(null, docs);
});
});

Resources