I'm very new to node.js and mongodb so any help would be appreciated. I have tried using ensureIndex before AND after the collection.update operation but either way it starts erroring out it seems.
Could someone point me in the right direction?
app.post("/", function(req, res){
var jsonObj = req.body;
var username = jsonObj['Username'];
var longitude = jsonObj['longitude'];
var latitude = jsonObj['latitude'];
var geoJsonObj = {'Username': username, location: {"type" : "Point", "coordinates" : [longitude, latitude]}};
//res.send(req.body);
mongo.Db.connect(mongoUri, function (err, db) {
if (err)
res.send(null);
db.collection('catchmerequests', function(err, collection) {
if (err)
res.send(null);
db.collection.ensureIndex( { location : "2dsphere" }, function (err, collection) {
collection.update({'Username':username}, {$set: geoJsonObj}, {upsert:true}, function(err,result) {
if (err)
res.send(null);
else
res.send(jsonObj);
});
});
});
});
});
Running the following code without the ensureIndex works perfectly!
Fixed it! You have to call ensureIndex on the database (not the collection), and pass the collection as the first parameter, followed by the index.
Related
In my node.js app I want to query multiple mongodb collections in a series using mongoose with the async plugin based on result from the first callback in the series.
So far I have this working code but I'm sure there is a better way of doing it async:
router.route('/project/:projectId')
.get(function(req, res) {
var getProjectDetails = function(cb) {
models.Project.findById(req.params.projectId, function(err, project) {
if(err)
res.send(err);
models.Media.find({'project_code' : project.code }, function(err, media) {
cb(null, {'project' : project, 'media': media})
});
})
}
async.parallel([getProjectDetails], function(err, result) {
res.render('details', {data: result});
});
});
As you can see I want to find all entries from the Media collection where project_code equals code from Project collection.
How can I acvhieve this without nesting my mongoose-querys?
Why do you need async in this? I hope this will work.
router.route('/project/:projectId')
.get(function(req, res) {
models.Project.findById(req.params.projectId, function(err, project) {
if(err)
return res.send(err);
models.Media.find({'project_code' : project.code }, function(err, media) {
if(err)
return res.send(err);
return res.render('details', {data: {'project' : project, 'media': media}});
});
});
});
Using a MEAN Stack deployment on Heroku I am able to GET and DELETE Documents with mongoDB's findOne and deleteOne functions. However when I try to PUT a document with the mongoDB updateOne/update function, I receive this error (server side) :
The _id field cannot be changed from {_id: ObjectId('56d4d71191fdc81100974d0b')} to {_id: "56d4d71191fdc81100974d0b"}.
Seems strange because I am using the same method in my server code for updateOne as in findOne (again, findOne works fine):
app.get("/contacts/:id", function(req, res) {
db.collection(CONTACTS_COLLECTION).findOne({ _id: new ObjectID(req.params.id) }, function(err, doc) {
if (err) {
handleError(err.message, "Failed to get contact");
} else {
res.status(200).json(doc);
}
});
});
app.put("/contacts/:id", function(req, res) {
var updateDoc = req.body;
db.collection(CONTACTS_COLLECTION).updateOne({_id: new ObjectID(req.params.id)}, updateDoc, function(err, doc) {
if (err) {
handleError(err.message, "Failed to update contact");
} else {
res.status(204).end();
}
});
});
Any suggestions?
I think you have problem at var updateDoc = req.body
As req.body contains id field and you are searching from object to update by that id, mongodb thinks you are trying to update
id field too which is not allowed.
One solution is to remove id field from your updateDoc object.
e.g.
delete updateDoc._id;
now try again and see if it works.
Your final function should look like
app.put("/contacts/:id", function(req, res) {
var updateDoc = req.body;
delete updateDoc.id;
db.collection(CONTACTS_COLLECTION).updateOne({_id: new ObjectID(req.params.id)}, updateDoc, function(err, doc) {
if (err) {
handleError(err.message, "Failed to update contact");
} else {
res.status(204).end();
}
});
});
I am building a mean stack app.
When I use this :
router.get('/courses/:course', function (req, res) {
res.json(req.course);
});
I get back the full object. But when I do this :
router.get('/courses/:course/reviews', function (req, res){
res.json(req.course.reviews);
});
I only get back the reviews ID, not the full elements like I whished it did.
Any idea why ?
EDIT :
Answering questions :
here is router.param :
router.param('course', function (req, res, next, id) {
var query = Course.findById(id);
query.exec(function (err, course){
if(err) { return next(err);}
if(!course) {return next(new Error('can\'t find course'));}
req.course = course;
return next();
});
});
Course is a model :
var CourseSchema = new mongoose.Schema({
code: String,
name: String,
courseContentGrade: Number,
courseTeachingGrade: Number,
courseAverage: Number,
reviews: [{ type: mongoose.Schema.Types.ObjectId, ref: 'review'}]
});
You need to populate the review field using mongoose.populate().
Below is a revised router.param, note the addition of the populate method to the query.
router.param('course', function (req, res, next, id) {
var query = Course.findById(id).populate('reviews');
query.exec(function (err, course){
if(err) { return next(err);}
if(!course) {return next(new Error('can\'t find course'));}
req.course = course;
return next();
});
});
Documentation: http://mongoosejs.com/docs/populate.html
I have this function to retrieve a specific user from a mongo db:
exports.findById = function(req, res){
var id = req.params.id;
db.collection('Users', function(err, collection){
collection.findOne({'_id':new BSON.ObjectID(id)}, function(err, item){
findPhotoByUserId(item._id, function(photo){
console.log('photo: ' + photo);
});
});
});
};
And this other to get the photo of the user, passing to it the Id of the user:
var findPhotoByUserId= function(userId, cb){
db.collection('Photos', function(err, collection){
collection.findOne({'userId': userId}, function(err, item){
if(!err)
cb(item);
});
});
};
Problem: the photo item is being null when i call the function "findById". However, if i put the explicit User Id here "collection.findOne({'userId': '522bae4a3ee1be8005000001'}....", the function returns the expected photo item.
Can someone help me about this issue?
Thanks!
I had the same problem. I got my code to work by using ObjectID in the 'mongodb' library:
var ObjectID = require("mongodb").ObjectID;
//more code here
query._id = { $gt: ObjectID(myId) }
Well, i solved my problem!
At this function:
var findPhotoByUserId= function(userId, cb){
db.collection('Photos', function(err, collection){
collection.findOne({'userId': userId.toString()}, function(err, item){
if(!err)
cb(item);
});
});
};
the 'userId' must be converted do a string.
Thanks!
I'm trying to get the result of query but i get the same info in all vars: db, collection and res:
var mongodb = require("mongodb");
var mongoserver = new mongodb.Server("localhost", 27017);
var instance = new mongodb.Db("test", mongoserver);
instance.open(function(err, db)
{
console.log('db:');
console.log(db);
db.collection('kurtsoa', function(err, collection)
{
console.log('collection:');
console.log(collection);
collection.find({}, function(err, res)
{
console.log('res:');
console.log(res);
});
});
});
how i can get the result of "find"?
.find() will return a Cursor object for you to work with. If all you are interested in is getting all the results in an array you can do:
collection.find().toArray(function(err, docs) {
console.log(docs);
});
But you can also iterate the cursor too:
collection.find().each(function(err, doc) {
//called once for each doc returned
});
You can use this:
collection.find().toArray(function(err, docs){
console.log(docs);
)};