How to get data and count in one query in mongoose - node.js

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

Related

How to get number of documents by using find method express 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});

mongooseJS find returning all rows

On using mongoose find with a condition such as
var condition= $and:[{'Credentials.UserName' : 'param.uName'},
{'Credentials.Password' : 'param.Pwd'}]
Here param.uName and param.Pwd are actual values entered by the user, which is set within inverted comma programatically.
Its returning all records in the mongodb table.
On using
.findOne({condition},schema,(err,data){
res.send(data)
})
It always returns the first row everytime.
I am sure that am missing something. Where is it/What is it?
Am new to mongoose. Thanks in Advance.
Edward
you can try something like:
mongooseObject.find({condition}, function(err, data) {
if (err)
handle the error
else {
data should be an array of all matches
}
});

Loopback query which compares field values

Say i have the following Scheme
Product: {
Quantity: Number,
SelledQuantity: Number
}
Would it be possible to write a query where all the results returned are where Quantity=SelledQuantity?
If so, is there a way to use it when doing a populate? (Perhaps inside the match field in the opts object ?)
I use mysql connector.
yes as I understood your problem you can do this by following rest call.
http://localhost:3000/api/products?filter[where][SelledQuantity]=n
this will give you the desired results.
This question is more related to MySQL query. But you can achieve it by javascript as follows:
Product.find({}, fuction(err, products) {
if(err) throw err;
//considering products as array of product. Otherwise you can get to depth for array of product.
var filteredProducts = products.filter(function(p1) {
return p1.Quantity === p1.SelledQuantity;
});
//Your desired output
console.log(filteredProducts);
});
This will be slow but will work for smaller database size. For more optimized answer, ask the question in mysql section with respect to database and table structure.

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.

Limit find using Monk in mongoDB

I have a large collection of documents.
I want to get the first 100 of these.
From the Monk Docs, this is the find method I am using
var documents = [];
users.find({}, function (err, docs){
for(i=0;i<100;i++)
documents.push(docs[i]);
});
This is highly wasteful since, the entire documents are anyway retrieved.
I want something like this (from the mongodb docs)
docs = db.users.find().limit( 100 );
I tried in monk,
users.find({}, function (err, docs){
for(i=0;i<docs.length;i++)
documents.push(docs[i]);
}).limit(100);
But it gives an error saying that there is no function limit in the "promise" object that is returned before it.
Is there such an option in Monk to limit the number of documents?
Yes, you can pass it as an option in the second parameter:
users.find({}, { limit : 100 }, function (err, docs){
for(i=0;i<docs.length;i++)
documents.push(docs[i]);
});
This comes from the native node mongodb driver, which monk wraps via mongoskin:
http://mongodb.github.io/node-mongodb-native/markdown-docs/queries.html#query-options
You could pass options object as a second parameter to .find():
users.find({}, {limit: 100}, next);
If you want add pagenumber and sorting, here is how to do it with monk:
users.find({}, {limit: 100, skip: pagenumber, sort: {'username': 1}})
where limit is for page size, skip is page number, sorting result by username ascending.

Resources