MongooseJS findAndUpdate within Find loop - node.js

Been banging my head in the wall on this, so any help would be greatly appreciated. With MongooseJS, I'm doing a Model.find and then looping through those results and doing a findAndUpdate.
(basically, get list of URLS from MongooseJS, "ping" each URL to get a status, then update the DB with the status).
Schema
var serverSchema = new Schema({
github_id: { type: String, required: true },
url: { type: String, required: true },
check_interval: Number,
last_check: {
response_code: Number,
message: String,
time: Date
},
created_at: Date,
updated_at: Date
})
Here's a code snippet:
// Doesn't work
Server.find(function (err, items) {
if (err) return console.log(err)
items.forEach(function (item) {
var query = {url: item.url}
Server.findOneAndUpdate(query, {updated_at: Date.now()}, function (err, doc) {
if (err) return console.log(err)
console.log(doc)
})
})
})
// Works!
var query = {url: 'https://google.com'}
Server.findOneAndUpdate(query, {updated_at: Date.now()}, function (err, doc) {
if (err) return console.log(err)
console.log(doc)
})
With debugging on, I can see that the .find() is getting the data I want. However, it seems that he findOneAndUpdate within the .find() never runs (item.url is set correctly) and I don't get any errors, it just doesn't run.
Any help would be GREATLY appreciated.

You can achieve that without find and then update you can do this in only one update operation
Server.update({}, { $set: { updated_at: Date.now() } }, function(err, doc) {
if (err) return console.log(err) {
console.log(doc)
}
})
In case you need to loop on items for specific reason to handle urls then try the code below
var Server = require('../models/server');
Server.find(function(err, items) {
if (err) {
return console.log(err)
} else {
items.forEach(function(item) {
var query = { url: item.url }
Server.update(query, { $set: { updated_at: Date.now() } }, function(err, doc) {
if (err) return console.log(err)
console.log(doc)
})
})
}
})
Mongodb Connection:
var secrets = require('./secrets');
var mongoose = require('mongoose');
module.exports = function() {
var connect = function() {
var mongoLink = "";
if (process.env.NODE_ENV === 'production') {
mongoLink = secrets.db.prod;
} else {
mongoLink = secrets.db.dev;
}
mongoose.connect(mongoLink, function(err, res) {
if (err) {
console.log('Error connecting to: ' + mongoLink + '. ' + err);
} else {
console.log('Connected to: ' + mongoLink);
}
});
};
connect();
mongoose.connection.on('error', console.log);
mongoose.connection.on('disconnected', connect);
}

Related

How to use findByIdAndUpdate on mongodb?

I am a noobie in coding and I am having an issue with how to use properly MongoDB. I have a parent object classroom containing an array of objects - comments. I am trying to update the content of 1 selected comment.
originally I updated the state of the whole "classroom" in the react and passed all the data and $set {req.body} in findByIdAndUpdate.
I want to achieve the same result if I only pass to my axios request classId, commentId and comment data and not whole classroom / all comments
I tried to filter selected comment out of the array of comments and concat updated comment, but that did not work. Clearly, I have any idea what is going on and docs don't make it any easier for me to understand.
my classroom schema:
var ClassroomSchema = new Schema({
title: String,
teacher: String,
info: String,
image_url: String,
comments: [Comment.schema]
});
comment schema:
var CommentSchema = new Schema()
CommentSchema.add({
content: String,
comments: [CommentSchema],
created_at: {
type: Date,
default: Date.now
}
});
original solution:
function update(req, res){
Comment.findById(req.params.comment_id, function(err, comment) {
if(err) res.send(err)
comment.content = req.body.content;
comment.save();
console.log(req.body.comments)
Classroom.findByIdAndUpdate(req.params.classroom_id,
{$set: req.body}, function(err, classroom){
if (err) {
console.log(err);
res.send(err);
} else {
commentToUpdate = req.body.commentData;
res.json(classroom);
}
});
});
}
my current failing atempt:
function update(req, res){
console.log('update => req.body: ', req.body);
console.log('req.params', req.params)
Comment.findById(req.params.comment_id, function(err, comment) {
if(err) res.send(err)
comment.content = req.body.content;
comment.save();
console.log('comment: ', comment);
Classroom.findById(req.params.classroom_id, function(err, classroom) {
console.log('CLASSROOM findByIdAndUpdate classroom: ', classroom)
// console.log('reg.body: ', req.body)
if (err) {
console.warn('Error updating comment', err);
res.send(err);
} else {
// commentToUpdate = req.body.commentData;
old_comments = classroom.comments;
console.log('comments: ', old_comments);
Classroom.findByIdAndUpdate(req.params.classroom_id,
{$set:
{ comments: old_comments.filter(comt._id !== comment._id).concat(comment)}
}, function(err, updatedClassroom) {
if (err) {
console.warn(err);
} else {
res.json(updatedClassroom);
}
});
}
});
});
}
haven't tested, but try this.
function update(req, res) {
Classroom.update(
{ _id: req.params.classroom_id, "comments._id": req.params.comment_id },
{ $set: { "comments.$.content": req.body.content } },
function(err) {
..
}
);
}

How to delete Element In MongoDB property's array with MongooseJS?

I cannot remove an element inside of an array that is a property of a MongoDB Model.
Please remember this is a NodeJS module mongooseJS and not the real MongoDB so functionalities are not the same..
GOAL: Delete an object from the statusLiked array. | I have also confirmed that the value of status.id is correct.
Model:
Const userSchema = new mongoose.Schema({
myStatus: Array,
statusLiked: Array,
)};
Delete:
1. Deletes the status(works). 2. Delete the status from User.statusLiked(no work).
exports.deleteStatus = (req, res, next) => {
var CurrentPost = req.body.statusid; // sends in the status.id
Status.remove({ _id: CurrentPost }, (err) => {
if (err) { return next(err); }
// vvvv this vvv
User.update( {id: req.user.id}, { $pullAll: {_id: CurrentPost }, function(err) { console.log('error: '+err) } });
req.flash('success', { msg: 'Status deleted.' });
res.redirect('/');
});
};
What happens: The specific status(object) is deleted from the database. But the status still remains in the User.statusLiked array.
What I want to happen: Status to be deleted from the User.statusLiked array and the status to be deleted from the database. Then, reload the page and display a notification.
I got it to work somehow. Working code:
exports.deleteStatus = (req, res, next) => {
var CurrUser = req.body.userid;
var CurrentPost = req.body.post;
Status.remove({ _id: CurrentPost }, (err) => {
if (err) { return next(err); }
console.log('meeee'+CurrentPost+'user: ' +CurrUser);
req.flash('success', { msg: 'Status deleted.' });
res.redirect('/');
});
User.update(
{ _id: new ObjectId(CurrUser)},
{ $pull: { myStatus : { _id : new ObjectId(CurrentPost) } } },
{ safe: true },
function (err, obj) {
console.log(err || obj);
});
};

When deleting records from mongoDB, elastics is not syncing with it

Somebody please tell me why aren't syncing my mogoosastic and mongodb?
When I delete records from mongoDB, records still are seen, until the server is restarted. this is me search function
exports.search = function (req, res) {
if (!req.query.q) return res.status(400).send('No Query Provided')
log.error(req.query.q)
var query = {
query_string: {
filtered: {
query: {
multi_match: {query: req.query.q,}
},
filter: {term: {isDeleted: false}
}
}
}
}
User.search(query, (err, results) => {
if (err) return handleError1(res, err)
var ret = _.map(results.hits.hits, result => ({
userID: result._id,
_score: result._score,
name: result._source.name,
loc: result._source.loc,
info: result._source.info,
images: result._source.images,
}))
return res.send(ret)
})
}
And this one is my Schema declaration
isDeleted: {type: Boolean, required: true, default: false, es_indexed: true}
what is wrong with this code...
I added this line of code and everything was ok
.then(groups => {
return User.findById(uid).exec()
})
.then(user => {
let email = user.credentials.loginEmail + '_' + moment().format('YYYYMMDDEHHmmss')
if(app.get('env') === 'localtest') {
email = user.credentials.loginEmail + '_deleted'
}
user.credentials.loginEmail = email;
user.isDeleted = true;
user.updated.at = new Date();
user.save()
.then(user_ =>{
user.sendInfoUpdate()
return res.status(204).send()
})
.catch(err => {
return handleError(res, err)
})
})
.catch(err => {
return handleError(res, err)
})

How to implementing beforeDestroy methods in SailsJS?

I'm new using sails JS.
I have methods like this
beforeDestroy: function(borrow, next){
return Book.find({id:borrow.product})
.then(function(){
Book.update(borrow.product, {'isBorrowed' : false})
})
.then(function(){
next();
})
.catch(function(error){
next(error);
});
}
When I tried to destroy data book 'IsBorrowed' still true, how to fix this when tried t delete data, firstly find id and secondly, change data book IsBorrowed to be false? Thank Advance
Here is a solution (to your original question - just switch the isBorrowed logic around as you now need it):
book.js
module.exports = {
schema: true,
attributes: {
name: {type: 'string', required: true},
desc: {type: 'text'},
isBorrowed: {type: 'boolean', defaultsTo: false}
}
};
bookBorrowed.js
module.exports = {
schema: true,
attributes: {
book: {model: 'Book'}
},
beforeDestroy: function (criteria, next) {
var bookId = criteria.where.id;
console.log(bookId);
Book.update({id: bookId}, {isBorrowed: true})
.exec(function (err, updatedBook) {
if (err) {
next('no book..');
}
console.log('updated book', updatedBook);
next();
});
}
};
Your problem was that you should consider the relationship with id, not object.
Also, the criteria parameter passed into beforeDestroy has a where object, it isn't the model. Also, the update() function takes an object criteria, see above.
If you wish to test, replace your bootstrap.js with the following snippet:
module.exports.bootstrap = function (cb) {
var bk = {name: 'name', desc: 'desc', isBorrowed: false};
Book.create(bk).exec(function (err, book) {
if (err) {
cb(err);
}
console.log('book: ', book);
var bb = {book: book.id};
BookBorrowed.create(bb).exec(function (err, bkBorrowed) {
if (err) {
cb(err);
}
console.log('bkBorrowed: ', bkBorrowed);
BookBorrowed.destroy({id: bkBorrowed.id}).exec(function (err, bkBorrowed) {
if (err) {
cb(err);
}
cb();
});
})
});
};

Node.js:Typeerror cannot read property 'find' of undefined

I've been doing some research within these couple of days but got stuck while trying to test the codes that I got from the web.
var MongoClient = require('mongodb').MongoClient,
format = require('util').format;
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
if (err) {
throw err;
} else {
console.log("successfully connected to the database");
db.collection('chat', function(err, collection) {
collection.find({}, {
tailable: true,
awaitdata: true,
numberOfRetries: -1
})
.sort({
$natural: 1
})
.each(function(err, doc) {
console.log(doc);
})
});
}
db.close();
});
And the error is:
c:\Project\node_modules\mongodb\lib\mongo_client.js:406
throw err
^
Am I missing any external library/reference because the error says "Cannot read property 'find' of undefined".
mongodb version: "2.0.31"
You check for a possible error in your first callback, but not the second one. Instead of
db.collection('chat', function(err, collection) {
collection.find({}, {...
Try:
db.collection('chat', function(err, collection) {
if (err) {
throw err;
} else {
collection.find({}, {...
This won't make your code snippet do what you want, but it will let you find out what error is preventing it from working.
You didnt export the collection module correctly....
If suppose your model class is collection.js,
then at the end of the class, it should be
module.exports = { Collection}
Final code will look like,
const mongoose = require('mongoose')
var Collection = mongoose.model('Collection', {
a: {type: String},
b: {type: String},
c: {type: Number},
}
module.exports = { Collection}
You can also do it like this:
collection.find((err, data) => {
if (err) {
console.log("An error: ", err);
} else {
console.log("My data", data);
}
});

Resources