AAAModel.find({'category' : category})
.skip(100)
.sort({date: 'desc'})
.exec(function(err, result) {
if (err) {
next(err);
}
if (result) {
result.remove();
}
});
the above doesn't work.
I would like to remove the 100 Items or more of the search results, what should I do?
You could try one of this approach:
Model.findOne({_id: 'specific_id'}, (err, doc) => {
doc.remove((err) => {
if (err) // handle err
});
// or simply use
doc.remove();
});
or
Model.findOne({_id: 'specific_id'}).remove((err, doc) => {
});
or
Model.remove({_id: 'specific_id'}, (err, doc) => {
});
Use this query
AAAModel.find(
{'category' : category},
{ skip: 100,sort:{date: -1}},
function(err, results) {
if (err) {
next(err);
}
if (result) {
result.remove();
}
});
I've got the same problem.
In fact in latest mongoose query has remove method. So, it theory it could work like this:
AAAModel.find({'category' : category})
.skip(100)
.sort({date: -1})
.remove(function(err, result) {
if (err) {
next(err);
}
if (result) {
console.log("Number of deleted records:" + result);
}
});
But in my case this code removed all records
So, the possible solution is
AAAModel.find({'category' : category})
.select("_id")
.skip(100)
.sort({date: -1})
.exec(function(err, idObjLst) {
if (err) {
return next(err);
}
var ids = idObjLst.map(function(idObj) { return idObj._id; });
if (ids && ids.length > 0) {
AAAModel.remove({_id: {$in: ids}}).exec(function(err, result) {
console.log("Removed " + result + " elements");
});
});
Could be quite expensive though.
As we know, the parameter results is an array of documents in your find callback, not a single document. so you can iterate it and remove item one by one, despite this is not best way to remove documents for performance.
Actually, mongoose Mode.remove can be used to remove documents, but the query condition can not skip and sort until now.
Related
I am trying to asynchronously retrieve some data from a database and then append those values in an array I need for some other things, I have this function:
function retrieveProduct(SKU, callback) {
Products.find({
SKU: key
}, function (err, doc) {
if (err) {
callback(err, null);
} else {
callback(null, doc[0]);
}
});
}
and I use it like this:
for (var key in orders) {
retrieveProduct(key, function (err, doc) {
if (err) {
console.log(err);
}
products_found[key] = doc
console.log(doc);
});
}
console.log(products_found);
}
Where orders is a list of IDs.
The problem is that when I try to append doc to products_found nothing is being appended and nothing is logged to the console. Moreover, ESlint is telling me not to make functions within a loop.
What am I doing wrong?
Hi I have a problem running a loop and getting the return data using Promises.
I have a getStudentMarks method for getting students marks from the database in subject wise.
getStudentMarks: function(studentId, studentStandard) {
console.log("getStudentMarks invoked...");
return new Promise(function(resolve, reject) {
r.table('student_subjects').filter({
"studentId": studentId,
"studentStandard": studentStandard
}).pluck("subjectId", "subjectName").run(connection, function(err, cursor) {
if (err) {
throw err;
reject(err);
} else {
cursor.toArray(function(err, result) {
if (err) {
throw err
} else {
console.log(result.length);
if (result.length > 0) {
studentSubjectArray = result;
var studentMarksSubjectWiseArray = [];
studentSubjectArray.forEach(function(elementPhoto) {
r.table('student_marks').filter({
"studentId": studentId,
"subjectId": studentSubjectArray.subjectId
}).run(connection, function(err, cursor) {
if (err) {
throw err;
reject(err);
} else {
cursor.toArray(function(err, result_marks) {
var studnetMarksDataObject = {
subjectId: studentSubjectArray.subjectId,
subjectName: studentSubjectArray.subjectName,
marks: result.marks
};
studentMarksSubjectWiseArray.push(studnetMarksDataObject);
});
}
});
});
resolve(studentMarksSubjectWiseArray);
}
}
});
}
});
});
}
I'm invoking the method by,
app.post('/getStudentMarks', function(req, reqs) {
ubm.getStudentMarks(req.body.studentId, req.body.studentStandard)
.then((data) => {
console.log('return data: ' + data);
})
.catch((err) => {
console.log(err);
});
});
When I run the code its working absolutely fine there is no error. I get all the student marks object in the studentMarksSubjectWiseArray array. But the problem is even before the studentSubjectArray loops gets completed, the resolve is getting executed and I'm getting a blank array as return. How do I solve the problem. I understand that I'm not doing the Promises right. I'm new to Promises so I'm not being able to figure out the right way.
That happens because inside your studentSubjectArray.forEach statement you perform set of asynchronous operations r.table(...).filter(...).run() and you push their result into the array. However, those actions finish after you perform the resolve(), so the studentMarksSubjectWiseArray is still empty. In this case you would have to use Promise.all() method.
let promisesArray = [];
studentSubjectArray.forEach((elementPhoto) => {
let singlePromise = new Promise((resolve, reject) => {
// here perform asynchronous operation and do the resolve with single result like r.table(...).filter(...).run()
// in the end you would perform resolve(studentMarksDataObject)
r.table('student_marks').filter({
"studentId": studentId,
"subjectId": studentSubjectArray.subjectId
}).run(connection, function(err, cursor) {
if (err) {
throw err;
reject(err);
} else {
cursor.toArray(function(err, result_marks) {
var studnetMarksDataObject = {
subjectId: studentSubjectArray.subjectId,
subjectName: studentSubjectArray.subjectName,
marks: result.marks
};
resolve(studnetMarksDataObject);
});
}
});
});
promisesArray.push(singlePromise)
});
Promise.all(promisesArray).then((result) => {
// here the result would be an array of results from previously performed set of asynchronous operations
});
I'm looking for a very simple way to duplicate a document in my DB but can't find a way to do it.
I have 2 models with the exact same schema.
What i'm doing is
1stDB.findOne({id:"1"}, function(error, results){
if(!error){
var 2ndb = new 2nDB(results);
2nd.save(function (err) {
if (err) {
return err;
}
else {
console.log("SUCCESSFULL");
}
});
}
})
There seems to be an issue as in my console results is formatted properly but just wont save.
But if i do it manually : 2ndb.anyfield = anyvalue it works.
I think it might have to do with promise ? but i'm not very familiar with the concept and might be wrong.
I've tried this :
1stDB.findOne({id:"1"}, function(error, results){
if(!error){
var 2ndb = new 2nDB(**{results}**);
2nd.save(function (err) {
if (err) {
return err;
}
else {
console.log("SUCCESSFULL");
}
});
}
})
and this ( In the hope that deleting the _id and keeping my custom .id field to identify similar document but still having an uniq _id by document would work but it didn't )
1stDB.findOne({id:"1"}, function(error, results){
if(!error){
**var objectResponse = results;
delete objectResponse._id;**
var 2ndb = new 2nDB(results);
2nd.save(function (err) {
if (err) {
return err;
}
else {
console.log("SUCCESSFULL");
}
});
}
})
You can use the following to achieve the required results
1stDB.findOne({id:"1"}).lean().exec(function(error, results){
if(!error){
var objectResponse = results;
delete objectResponse._id;
var 2ndb = new 2nDB(objectResponse);
2nd.save(function (err) {
if (err) {
return err;
}
else {
console.log("SUCCESSFULL");
}
});
}
})
If the lean option is not used, mongoose will return a mongoose object instead of a simple json. This is why you were not able to pass the result directly to the constructor of the 2nd schema. Using the lean query the response will be a plain JSON object which can be passed to the constructor of the 2nd schema. For more information check this stackoverflow post on returning a plan object as response from mongoose
Let's say I have this schema
{
jedi: [{
name:String
lightsaber_color:String
]}
}
I want to return all and only the names of them.
I tried
Jedi.find({})
.select('jedi.name')
.exec(function (err, jedi) {
if (err) {
console.log("nothing found")
}
}
It returns me nothing, while this code returns me everything.
Jedi.find({})
.select('jedi')
.exec(function (err, jedi) {
if (err) {
console.log("nothing found")
}
}
I see that jedi is an array so I think that .select('jedi.name') may not work for this reason.
What is the right syntax to do so?
You can try with this
Jedi.find({}, {'jedi.name':1}, function (err, jedi) {
if (err) {
console.log("nothing found")
}
else{
console.log(jedi);
}
}
I'm using node-mysql-queues to handle database transactions in my application.
for (lineitem in lineitems) {
transaction.query("SELECT n from inventory WHERE productId = ?", [lineitem], function (err, rows) {
if (err)
transaction.rollback();
var newN = rows[0].n - lineitems[lineitem].quantity;
if (newN >= 0) {
transaction.query("UPDATE inventory SET n = ? WHERE productId = ?", [newN, lineitem], function (err) {
if (err){
transaction.rollback();
console.log(err);
}
//here I want to commit if all updates were successfull!!!
});
}
})
}
As you can see in the code, I don't know how to handle the commit part. If it was synchronous it would be easy, but don't know how ro solve this problem.
Thanks & Regards
This is easy with something like the async module.
async.each(lineitems, performQuery, function(err) {
if(err) {
transaction.rollback();
console.log(err);
return;
}
transaction.commit();
});
function performQuery(lineitem, callback) {
transaction.query("SELECT n from inventory WHERE productId = ?", [lineitem], function (err, rows) {
if (err) return callback(err);
var newN = rows[0].n - lineitems[lineitem].quantity;
if (newN >= 0) {
transaction.query("UPDATE inventory SET n = ? WHERE productId = ?", [newN, lineitem], function (err) {
if (err) return callback(err);
callback();
});
}
});
}
I found a solution for my problem. Since I had problems with doing a select and then an update depending on the result of the select, I implemented something like a conditional update.
But see my code:
mysql.getTransaction(function (err, transaction) {
//For each item in the cart, call the performUpdate method
//If an error occures, rollback the whole transaction
async.each(lineitems, performUpdate, function (err) {
if (err) {
transaction.rollback();
res.json(err.message);
return;
}
//Since we are going to call another callback, we need to pause the transaction, else it would be committed automatically
transaction.pause();
//If the Updates were successfull, create an Order in MongoDB
orderController.createMongoOrder(lineitems, req.session.cart.total, req.session.passport.user, function (err) {
if (err) {
//If there is a Problem with Mongo, cancel the transaction
transaction.resume();
transaction.rollback();
res.json(err.message);
} else {
//Else commit the transaction and empty the cart
transaction.resume();
transaction.commit();
req.session.cart = {
products: {},
count: 0,
total: 0
};
res.json("Order accepted!");
}
})
});
function performUpdate(lineitem, callback) {
//This query can be seen as conditional update. If the number of articles in stock is not sufficient, there will be no affectedRows in the returned info message
transaction.query("UPDATE inventory SET n = n -? WHERE productId = ? AND n >= ?", [lineitem.quantity, lineitem.id, lineitem.quantity],function (err, info) {
if (err) {
return callback(err);
} else {
//if for any item there is no affectedRow, this means the Updated failed. This should make the whole transaction roll back so we return an error to the callback
if (info.affectedRows != 1) {
return callback(new Error("Article: " + lineitem.productObject.name + " out of stock!"))
}
return callback(null, info);
}
}).execute()
}
})