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
Related
Am using Nodejs and MongoDB and I am new to nodejs. I need to know how to get data from one collection and append some additional data and insert into another collection.
db.collection('collection1').find({ "Id" : 12345 }).toArray(function(err, result){
db.collection('collection2', function(err, collection){
collection.insert({
//some data
})
})
})
When I try this code its not working its giving me error insert is not defined.
thanks,
John.
db.collection('collection1').find({ "Id" : 12345 }).toArray(function(err, result){
//do the modification here
db.collection('collection2').insert(modifiedResult, function(err, result){
if(err) {
//log error
}else{
//log result
}
})
})
One more thing, If the result array length is more that one and you want to insert then separately then use promise
db.collection('collection1').find({ "Id" : 12345 }).toArray(function(err, result){
//do the modification here
Promise.all(modifiedResult.map((eachModifiedResult)=>{
return db.collection('collection2').insert(eachModifiedResult);
}).then((result)=>{
//result of the insert
}).catch((err){
//err if any happen
});
})
But if you have a very large doc then do it as Neil Said. Read the collection one by one using cursor and modify them and insert them to other db.
You can use callback library like async or Promises Q
Promise
var collectionData = null;
var modifiedResult = null;
// here i am using async library to avoid callbackHell
async.series([
// for get data from collection 1.
function(cb) {
var criteria = {
"Id": 12345
}
db.collection('collection1').find(criteria).toArray(function(dbErr, dbResult) {
if (err) {
cb(dbErr)
} else {
collectionData = dbResult;
cb()
}
})
},
// Append Data in collectionData
function(cb) {
// do you work here to append data in collectionData
modifiedResult = extendedData; // this is just an example you need to work on it
cb();
},
// Update collection 2 here
function(cb) {
db.collection('collection2').insert(modifiedResult, function(err, result) {
if (err) {
cb(dbErr)
} else {
collectionData = dbResult;
cb()
}
});
}
]);
I'm currently working on a route the returns an array which contains the results from two separate calls to the database. Individually the functions I call in the model functions work as intended. However, when I attempt to combine them by calling the second function within the callback of the first I receive an error that the second function "is not a function". Here is the code in my list route. Note util and errorhandler are files I've created to help with the return format and shouldn't be effecting this error. Any help solving this would be appreciated, Thank you!
route/list
router.route("/list/:id").get(function(req, res) {
list.getListMovie(req.params.id, function(err, list) {
if (err) {
res.json(errorHandler.handleDatabaseErrors(err));
return;
}
var response = [];
response["movies"] = list;
console.log(response)
list.getListTV(req.params.id, function(err, list1) {
if (err) {
res.json(errorHandler.handleDatabaseErrors(err));
return;
}
response["tv"] = JSON.parse(list1);
console.log(response)
res.json(utils.returnFormatForDB(response));
});
});
});
the function definitions within models/list
exports.getListTV = function(userid, done) {
db.get().query('SELECT `idmedia`, `rating`, `title`, `poster_path` FROM
`list` JOIN `tv` ON list.idmedia = tv.tv_id WHERE list.idusers = ?', userid,
function(err, rows) {
if (err) return done(err);
done(null, rows);
});
}
exports.getListMovie = function(userid, done) {
db.get().query('SELECT `idmedia`, `rating`, `title`, `poster_path` FROM
`list` JOIN `movies` ON list.idmedia = movies.movie_id WHERE list.idusers =
?', userid, function(err, rows) {
if (err) return done(err);
done(null, rows);
});
}
EDIT:: I'm not sure of the proper way to mark a question as answered but by fixing the list override and making response an object I was able to get my code to work. Thanks for the help!
You are overwriting the list variable. Try
list.getListMovie(req.params.id, function(err, movieList) {
if (err) {
res.json(errorHandler.handleDatabaseErrors(err));
return;
}
var response = {};
response["movies"] = movieList;
console.log(response)
list.getListTV(req.params.id, function(err, tvList) {
if (err) {
res.json(errorHandler.handleDatabaseErrors(err));
return;
}
response["tv"] = JSON.parse(tvList);
console.log(response)
res.json(utils.returnFormatForDB(response));
});
});
Also, I'm pretty sure you want the response variable to be an object, not an array.
I am trying to find record by id but it not getting done
var id = req.param('id');
var item = {
'_id': id
}
videos.find(item, function(error, response) {});
I have give a valid id but still it is not fetching,can anyone suggest help,please.
There is a callback provided to find() but in your code above, it has no executable statements. Instead of this:
videos.find(item, function(error, response) {});
...do something like this:
videos.find(item, function(error, response) {
if (error) {
console.log(error); // replace with real error handling
return;
}
console.log(response); // replace with real data handling
});
You have to use callbacks for error handling. And find() returns array. If you need to find user by unique key (in this case _id) you must use findOne()
router.get('/GetVideoByID/:id',function(req,res){
var id = req.params.id;
var video = {
'_id' : id
}
videos.findOne(video,function(err,data){
if(err){
console.log(err);
}else{
console.log("Video found");
res.json(data);
}
});
});
Here is the nodejs code I'm using to update the document in the mongoDB, req.body contains the document which was send as an post request to the nodejs server,
it is not throwing any errors but not updating the document too, any suggestions why this is happening;
router.route('/results').post(function(req,res){
var toupdate = req.body;
delete toupdate._id;
console.log(toupdate)
Question.update({_id:req.body._id}, toupdate, function(err){
if(err){
console.error(err.stack);
}
});
// even tried Question.update({_id:req.body._id}, {$set:{questions:toupdate.question}});
});
I also tried using findById and then saving the document this time got 500 as an response:
router.route('/results').post(function(req,res){
var toupdate = req.body;
delete toupdate._id;
console.log(toupdate)
Question.findById(eq.body._id, function (err, tank) {
if (err){
console.log(err.stack);
return handleError(err);
}
toupdate.save(function (err){
if (err){
console.log(err.stack);
return handleError(err);
}
});
});
});
Thanks for the support, tried your solution JohnnyHK but it didn't work, but found a way to update the document, had to assign fields of req.body to the fields of an object, here :
router.route('/results').post(function(req,res){
Question.findOne(req.body._id, function (err, questions) {
if (err) return handleError(err.stack);
questions.question = req.body.question;
questions.options = req.body.options;
questions.difficulty = req.body.difficulty;
questions.type = req.body.type;
questions.answer = req.body.answer;
questions.domainof = req.body.domainof;
questions.topic = req.body.topic;
questions.weightage = req.body.weightage;
questions.created_by = req.body.created_by;
questions.save(function (err){
if (err) return handleError(err.stack);
console.log(questions);
});
});
});
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