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?
Related
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
How can I update ALL documents in a collection where an attributes value needs to be different (a unique number) for each document?
Below is my current code. This actually seems to update (I don't get an error) but the values in the db are not being updated.
Model.find({}, function (err, docs) {
if (err) {
console.log(err);
};
if(docs && docs.length > 0){
for(var i=0; i<docs.length; i++){
//SET NEW VALUE FOR EACH DOC - VALUE MUST BE UNIQUE TO EACH DOC
docs[i].code = generateRandomCode();
}
// PASS IN ARRAY OF UPDATED DOCS TO BE SAVED
Model.update(docs, function (err, docs) {
if (err) {
console.log(err);
}
if(!err){
req.updatedSuccessfully = true;
}
return next();
});
}
else{
return next();
}
});
Before this I was trying to do something like this:
Model.update({}, { code: generateRandomCode() }, { multi: true }, function (err, numberAffected, raw) {
if (err) return handleError(err);
console.log('The number of updated documents was %d', numberAffected);
console.log('The raw response from Mongo was ', raw);
});
The problem with this is that generateRandomCode() is only called once but I need to create a different code for each document. So neither of these example work.
Instead of trying model.update(), can you try to simply save the documents?
See answer to this question on this url: Update model with Mongoose, Express, NodeJS
I have an array of documents with unique _id and I want to insert them to my database. Some of them already in db, and for those I want to update an array property (push in array an item). All of this I need to make asyncronuosly, so after all inserted/updated I want to write response back (with callback) to client than all ok or write an error. After googling on subject I've found this solution with async module I've tried to implement it for my case. Now my code looks like this:
function processUsers(arr, listName, callback) {
var users = global.db.collection('vkusers');
var q = async.queue(function(task, cb) {
console.log('upsert butch');
users.insert(task.doc, function(err, doc) {
if (err) {
users.update({
_id : task.doc._id
}, {
$addToSet : {
mLists : listName
}
}, function(error, result){ console.log(error); console.log(result); });
}
});
}, arr.length);
for ( var doc in arr) {
q.push({
doc : arr[doc]
}, function(err) {
if (err)
callback(err, null);
})
}
q.drain = function() {
// this is the queue's callback, called when the queue is empty,
// i.e. when all your documents have been processed.
console.log('drain');
callback(null, { result: "success", upserted: arr.length });
}
}
Callback has signature callback(error, result), arr - my array of documents. I've tested it and with database everything is OK, i am getting the right result. But callback, and q.drain never fired!
You need to call async.queue's callback (cb in your code) when your insert/update is complete. Something like this:
var q = async.queue(function(task, cb) {
console.log('upsert butch');
users.insert(task.doc, function(err, doc) {
if (err) {
users.update({
_id : task.doc._id
}, {
$addToSet : {
mLists : listName
}
}, function(error, result) {
console.log(error);
console.log(result);
cb(error); // Update finished; call cb and pass in "error" so that it can bubble up if it exists
});
} else {
cb(); // Insert succeeded; call cb
}
});
}, arr.length);
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.
using MongoDB w node.js, I am trying to remove an item after finding it .. but it's failing
I get the collection (db.collection)
I find the item ( collection.findOne )
I remove the item from the collection
what's wrong in my script ?
exports.revokeRefreshToken = function (refreshToken, callback) {
db.collection('oauth_refresh_tokens', function(err, collection) {
collection.findOne({'refreshToken': refreshToken}, function(err, item) {
db.collection('oauth_refresh_tokens').remove({_id: item._id});
callback(err );
});
});
};
I modified the revoke function to include a callback
exports.revokeRefreshToken = function (refreshToken, callback) {
db.collection('oauth_refresh_tokens', function(err, collection) {
collection.remove({'refreshToken': refreshToken} , function(err, result) {
callback(err);
});
});
};