nodejs filter for mongodb data - javascript

I am using node and MongoDB for my project, here I need to set the filter on node script so that the data comes out from my MongoDB is filtered. But I do not understood how to use filter functionality on my script. It will be a filtered method, or I can use find method, or use loop
to filter the data in my MongoDB using node js script.
I am not exactly getting the idea.
What I want to do?
1) I had sent a set off a question from my MongoDB to the frontend.
2) Questions Data is coming from the front end and saved via using node js API. I have to save questionId, a score.
3) Next time when I have to send the data I NEED FILTER HERE so that data I have sent previously not sent again.
Id will generate automatically in MongoDB. So I have not mention id here.
This is my question schema
title: {type: String, required:true},
options: {type: Array, required:true},
result: {type: Array, required:true},
here i am storing my questionid, score values coming from frontend.
This is my question id, score save schema
child: {
quiz: {
questionId:{type:String},
score:{type:Number},
time:{type:String}
}
}
This is my node js API filter. I am trying this but I am not sure this is right or wrong. Please help me to fix this proble.m
this.childfilter = function(req, res, next) {
async.waterfall ([
function(callback) {
try {
var query = { 'child.quiz.score': 1 };
var projection = '';
childinfo.find(query,function(err,data) {
if(err) return next(err);
res.send(data);
callback(null, data)
});
}
catch(err) {
console.log(err);
return next(err);
}
},
function(callback, data) {
try {
var childq = new childquestion();
var query = { 'data.child.quiz.questionId' : childq._id };
var projection = 'id title options result';
childquestion.find(query,projection)
.skip()
.exec(function(err,data){
if (err) return next(err);
res.send(data);
});
}
catch(err) {
console.log('Error While Saving the result ' +err);
return next(err);
}
}
]);
}

Related

Creating new mongoose sub-doc and appending to existing parent doc

I'm building a website with a database using NodeJS, MongoDB, Express, Mongoose etc.
I have two schema set up: Events and a sub-doc schema Categories (among others).
The function pulls in array which contains the data needed to create several categories (this bit works) as well as the Event ID appended to the end.
The first few bits below just grab that ID, then remove it from the array (probably a better way to do this, but again, it works).
As mentioned above, the Categories then create correctly (and even do validation), which is amazing, BUT...
They don't get appended to the Event doc. The doc updates the "categories" field to an applicable number of "null" values, but I cannot for the life of me get it to actually take the IDs of the newly created categories.
I nabbed (and adjusted) the below code from somewhere, so this is where I'm at...
exports.addCategories = catchAsync(async (req, res, next) => {
const categories = req.body;
const length = categories.length;
const eventID = categories[length - 1].eventId;
categories.pop();
Event.findOne({ _id: eventID }, (err, event) => {
if (err) return res.status(400).send(err);
if (!event)
return res.status(400).send(new Error("Could not find that event"));
Category.create(categories, (err, category) => {
if (err) return res.status(400).send(err);
event.categories.push(category._id);
event.save((err) => {
if (err) return res.status(400).send(err);
res.status(200).json(category);
});
});
});
});
Currently the mongoose debug output is showing the following (which confirms that MOST of it is working, but the IDs just aren't being pulled correctly):
> Mongoose: events.updateOne({ _id: ObjectId("614bc221bc067e62e0790875")}, { '$push': { categories: { '$each': [ undefined ] } }, '$inc': { __v: 1 }}, { session: undefined })
Nevermind! I realised that "category" was still an array, rather than an element of the categories array as I'd assumed.
So I replaced that section with this, and now... it works!
Category.create(categories, (err, categories) => {
if (err) return res.status(400).send(err);
categories.forEach((category) => {
event.categories.push(category._id);
});
event.save((err) => {
if (err) return res.status(400).send(err);
});
});

Append to array from mongodb query result and update database

I am developing an express webapp that has a friends list feature, the list is an array that is part of the user record in the database. What I am trying to do is to set up a route that adds the user from the route parameter to the logged in user's friends list array and updates the database.
My approach is to acquire the friends list document via collection.find() query (which works), modify it via javascript and update the database in a callback function.
The modifying part is what causes me problems, since the mongodb queries don't return json, but mongodb query objects. I don't know how to parse them. How can I get only the values to edit from that document?
router.get('/users/:specifiedUser/addfriend', function(req, res){
var currentUser = req.user.username;
var specifiedUser = req.params.specifiedUser;
var db = req.db;
var collection = db.get('usercollection');
var friendsList = [];
collection.find({ username : currentUser },{ friendsList : 1 }, function (err, result){
//TODO: convert result values to friendsList array, append specifiedUser to the array that is then updated in the callback
collection.update({username : currentUser },{friendsList : friendsList }, function (err) {
if (err) {
// return error if it fails
console.log(err.message);
return res.render('index', { error : err.message });
};
});
if (err) {
// return error if it fails
console.log(err.message);
return res.render('index', { error : err.message });
};
});
});

NodeJS is asynchronous and my code doesn't run in the order I am expecting

postRegistrationHandler: function (account, req, res, next) {
console.log('postRegistrationHandler activated');
account.getCustomData(function(err, data) {
if (err) {
console.log(err.toString, "error string");
return next(err);
} else {
data.mongo_id = userCreationCtrl(account);
data.save();
next();
}
});
},
This function almost works properly, but the line:
data.save();
runs before the previous line finishes which means that the data I want to save isn't present at the appropriate time.
data.mongo_id = userCreationCtrl(account);
This line calls a function that creates a mongoDB document with information in the account object and then returns the _id (which is what I am trying to save.
I thought maybe using a .then() would help but that seems to be unavailable here for some reason. If anyone sees something I'm missing, that would be quite helpful. Thank you!
Here is the userCreationCtrl file as requested:
var UserSchema = require('./../models/UserModel.js');
var createNewUser = function (account, res, next){
// We will return mongoId after it is created by submitting a newUser
var mongoId = "";
// Save StormpathID (last 22 characters of account.href property)
var newStormpathId = account.href.slice(account.href.length - 22);
console.log('stormpath ID:', newStormpathId, 'just registered!');
console.log(account);
// Create new user from model by recycling info from the Stormpath registration form and include the stormpathId as well.
var newUser = new UserSchema({
stormpathId: newStormpathId,
firstName: account.givenName,
lastName: account.surname,
email: account.email,
street: account.street,
city: account.city,
zip: account.zip
});
// This saves the user we just created in MongoDB
newUser.save(function(err, result){
console.log(result);
if (err) {
console.error(err);
}
else {
console.log("User created in MongoDB, attempting to return mongoDB _id to stormpath customData");
// Keep track of the new user's mongo _id so we can return it to the previous function and save it as Stormpath custom data.
mongoId = result._id;
console.log(mongoId, "mongoid");
return result._id;
}
});
};
module.exports = createNewUser;
You have userCreationCtrl expecting 3 arguments, account, res, and next. next is the callback that should be called after the user is created so instead of return result._id you should call next like so:
// inside of createNewUser()
newUser.save(function(err, result){
console.log(result);
if (err) {
console.error(err);
}
else {
console.log("User created in MongoDB, attempting to return mongoDB _id to stormpath customData");
// Keep track of the new user's mongo _id so we can return it to the previous function and save it as Stormpath custom data.
mongoId = result._id;
console.log(mongoId, "mongoid");
// IMPORTANT change to make it all work...
// get rid of return result._id because its not doing anything
// pass the value to your callback function instead of returning the value
next(null, result._id);
}
});
then calling code in postRegistrationHandler should look like this:
account.getCustomData(function(err, data) {
if (err) {
console.log(err.toString, "error string");
return next(err);
} else {
// pass in a callback as the 3rd parameter that will be called by newUser.save() when its finished
userCreationCtrl(account, null, function(err, resultId) {
data.save();
next();
});
}
});

MongooseJS Not saving to array properly

I want to append a value into my Mongoose array but my array never seems to update. I do the following:
In my controller, I append an eventName into the array eventsAttending like so:
$scope.currentUser.eventsAttending.push(event.eventName);
$http.put('/api/users/' + $scope.currentUser._id, $scope.currentUser)
.success(function(data){
console.log("Success. User " + $scope.currentUser.name);
});
I try to update the array like so:
// Updates an existing event in the DB.
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
User.findById(req.params.id, function (err, user) {
if (err) { return handleError(res, err); }
if(!user) { return res.send(404); }
user.markModified('req.body.eventsAttending');
user.save(function (err) {
if (err) { return handleError(res, err);}
return res.json(200, user);
});
});
};
But my array never seems to update. I've also tried the following:
// Updates an existing event in the DB.
exports.update = function(req, res) {
if(req.body._id) { delete req.body._id; }
User.findById(req.params.id, function (err, user) {
if (err) { return handleError(res, err); }
if(!user) { return res.send(404); }
var updated = _.merge(user, req.body);
updated.markModified('eventsAttending');
updated.save(function (err) {
if (err) { return handleError(res, err);}
return res.json(200, user);
});
});
};
With this approach, my array updates properly, but when I try to perform the http put after one time, I get an error saying Error: { [VersionError: No matching document found.] message: 'No matching document found.', name: 'VersionError' }
Here is my UserSchema:
var UserSchema = new Schema({
name: String,
username: String,
eventsAttending: [{ type: String, ref: 'Event'}],
});
If anyone could help that would be much appreciated.
My guess is the object returning from _.merge is no longer a Mongoose model and some information is getting lost in the transform. I would try manually setting all of the fields coming from the request and use events.attending.push() to add to the array, then saving the updated object and see what happens.
Your first example with markModified looks wrong. Looking at the documentation it should be the name of the field that is modified and it appears that you've put the source location for it.
user.markModified('user.eventsAttending')
However that should not be necessary if you use the push method as Mongoose overrides the built-in array function to track changes.

index a mongo db with javascript

I have working script which stores the html forms i have created in mongoDB. It works awesome. However, i can't search any of the data i place in mongo, because i don't have an index.
I realize I could create the index from the console, but for my system to work the way we need, I really need the index to be created when the data is stored. So, i need to place code in the javascript that actually creates the code 9using node.js or directly).
I tried the following javascript (with node.js), but it does not appear to work.
app.post('/:db/:collection/formSubmit', function(req, res) {
var json = form2json.transform(req.rawBody);
var db = new mongo.Db(req.params.db, new mongo.Server(config.db.host, config.db.port,mongoOptions ));
db.open(function(err, db) {
db.authenticate(config.db.username, config.db.password, function () {
db.collection(req.params.collection, function(err, collection) {
collection.insert(Array.isArray(json) ? json[0] : json, function(err, docs) {
res.header('Content-Type', 'application/json');
if(req.is('application/xml')) {
res.send('<ok>1<ok>')
} else {
es.send(json, 201);
}
// my attempt to create an index while posting a form follows
db.core.ensureIndex( { "document": 1 } )
db.close();
});
});
});
});
});
You need to call ensureIndex on the collection:
collection.ensureIndex({ "document": 1 }, function (err, indexName) {
db.close();
});

Categories

Resources