I have a problem. I renamed my collection responses into old. It works really well but now I need to retrieve my data and my impediment is that I only used the model to retrieve my data from a collection. But now I need to retrieve my data from my renamed collection but I have no model and schema. I tried to create a schema and a model but it didn't work. It returns no elements.
Here is a part of the code :
app.get("/Play", function(req, res) {
var urlTempBox = 'http://localhost:3000/Play';
///////////////////////////////////////////////////////////
request(urlTempBox, function(error, response, body) {
if (error) {
throw (error);
} else {
var jobj = JSON.parse(response.body);
persistRS(jobj);
setTimeout(function() {
ResponseDatabase.find()
.populate('unitCode')
.exec(function(err, finalData) {
if (err) throw (err);
mongoose.connection.db.listCollections({
name: 'old'
})
.next(function(err, collinfo) {
if (err) throw (err);
if (collinfo) {
console.log('lookinOld');
OldResponseDatabase.find()
.populate('unitCode')
.exec(function(err, oldData) {
if (err) throw (err);
console.log('itsOld');
console.log(oldData);
res.send(finalData);
});
} else {
console.log('fk');
res.send(finalData);
}
})
})
}, 5000);
}
});
Here is the part where it doesn't work: console.log(oldData) returns nothing. And I know that my data is in the database when I try to retrieve them.
if (collinfo) {
console.log('lookinOld');
OldResponseDatabase.find()
.populate('unitCode')
.exec(function(err, oldData) {
if (err) throw (err);
console.log('itsOld');
console.log(oldData);
res.send(finalData);
});
}
Finally I found how to do maybe it will be usefull for someone
You just need in your schema to precise the name of your collection like this
( collection : 'old' )
var nameSchemaOldRS = new mongoose.Schema({
MainClass: String,
BookingClass: String,
carID: String,
unitCode:{type: String, ref: 'Map' ,required: [true,'No post id found']},
Deck:Number,
Orientation:String,
Position:String,
}, {
versionKey: false,
collection : 'old'
},);
Related
I'm trying to figure out the best way to prevent duplicate documents from being saved in MongoDB.
Right now my form takes the user_url from the user. The logic is:
Check if the user_url is valid. (dns.lookup)
If user_url is new, save it to the database and return url_ID.
If user_url is old, just return the url_ID.
I think my 2 options are:
var findOneURL = function(user_url, done) {
URL.findOne({
orig_url: user_url
}, (err, data) => {
if (err) {
done(err);
}
done(null, data);
})
}
or
var findEditThenSave = function(user_url, done) {
URL.findById(user_url, (err, data) => {
if (err) {
done(err);
}
data.save((err, data) => {
if (err) {
done(err);
}
done(null, data);
});
})
};
It's not working terribly well at the moment but this is the live version:
https://kindly-fisherman.glitch.me/
EDIT2: I think I got it working properly now. Here's my logic:
Saving to database: dns.lookup -> findByURL -> (If it doesn't exist) -> countURLs -> findAndUpdateURL -> Return what was saved to database.
OR -> (If it exists) -> Return the record.
Retrieving from database: findByID
The best choice is findOneAndUpdate query with upsert and returnNewDocument options
db.collection.findOneAndUpdate({ orig_url: user_url }, { $set: { orig_url: user_url }}, { upsert: true, returnNewDocument: true })
In mongoose
URL.findOneAndUpdate({orig_url: user_url }, { $set: { orig_url: user_url }}, { upsert: true, new: true }, (err, data) => {
if (err) {
done(err);
}
// data will contain your document
done(null, data);
});
upsert option specifies whether to insert document if not found, new (returnNewDocument in mongo's console) - whether to return old or updated document - if false (default is false) you will have null for inserted documents.
Instead of using
db.insert()
you should use
db.update()
and specify
$upsert: true
[here]
When ever I try to just use a simple find() for my mongodb it returns undefined.
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/local';
MongoClient.connect(url, function (err, db) {
db.collection('pokemon').find({ $search: { $text: 'Pikachu' } }).toArray(function(err, data){ console.log(data) })
});
EDIT:
Turns out I never created an index by putting
db.collection('pokemon').createIndex({Name: 'text'})
before all the code.
First of all, every time where you have:
function(err, data){ console.log(data) }
you should check errors:
function (err, data) {
if (err) {
console.log('Error:', err);
} else {
console.log('Data:', data);
}
}
Then you will probably see what's going on.
This is also true for the database connection itself - instead of:
MongoClient.connect(url, function (err, db) {
// use db here
});
you should handle errors:
MongoClient.connect(url, function (err, db) {
if (err) {
// handle errors
} else {
// use db here
}
});
If you don't handle errors then don't be surprised that you don't know why you don't get values.
I have a problem pushing into my Student model data and its schema looks as below:
var StudentSchema = new Schema({
firstName: {
type: String,
trim: true,
default: ''
//validate: [validateLocalStrategyProperty, 'Please fill in your first name']
},
lastName: {
type: String,
trim: true,
default: ''
//validate: [validateLocalStrategyProperty, 'Please fill in your last name']
},
worksnap: {
user: {
type: Object
},
timeEntries : [],
},
timeEntries : []
});
While my javascript code for pushing items looks like this:
Student.findOne({
'worksnap.user.user_id': item.user_id[0]
})
.populate('user')
.exec(function (err, student) {
if (err) {
throw err;
}
//student.timeEntries.push(item); // this works
student.worksnap.timeEntries.push(item); // this does not work
student.save(function (err) {
if (err) {
//return res.status(400).send({
// message: errorHandler.getErrorMessage(err)
//});
} else {
console.log('item inserted...');
}
});
});
As you can see, if I use timeEntries array outside the worksnap object it works fine, it inserts the item as object into that array... I just don't know why it is not working the same being inside worksnap object.
Is there any other option that I can add json objects into an array type in mongo
Thanks
Use .lean()
Documents returned from queries with the lean option enabled are plain JavaScript objects, not MongooseDocuments. They have no save method, getters/setters or other Mongoose magic applied.
Student.findOne({
'worksnap.user.user_id': item.user_id[0]
})
.populate('user')
.lean()//-----Added!
.exec(function(err, student) {
if (err) {
throw err;
}
//student.timeEntries.push(item); // this works
student.worksnap.timeEntries.push(item); // this does not work
student.save(function(err) {
if (err) {
//return res.status(400).send({
// message: errorHandler.getErrorMessage(err)
//});
} else {
console.log('item inserted...');
}
});
});
EDIT: This question was asked earlier, but I didn't do a good job of asking it. I've rewritten the question. Thanks in advance for your help!
I'm in the process of writing a simple messaging server for a school project. Among its other functionalities, the server allows the user to update the information stored in their account. When the user does update their account, an authentication token is generated for them. Here's the schema that defines all of that. Note, header and body are parts of the user input:
UserSchema = new Schema({
_id: {type: ObjectId, select: false},
username: {type: String, required: true, index: {unique: true} },
password: {type: String, required: true, select: false},
email: {type: String},
token: {type: String, select: false}
}, {
autoIndex: false
});
UserSchema.pre("save", function(next) {
// Create a new token for the user
var self = this;
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
if (err) {
next(err);
} else {
crypto.randomBytes(256, function(err, bytes) {
if (err) {
next(err);
} else {
bytes = bytes.toString("hex");
bcrypt.hash((new Date() + bytes), salt, function(err, tokenHash) {
if (err) {
next(err);
} else {
self.token = tokenHash;
next();
}
});
}
});
}
});
});
UserSchema.pre("save", function(next) {
// Hash the password before saving
var self = this;
if (!self.isModified("password")) {
next();
} else {
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
if (err) {
next(err);
} else {
bcrypt.hash(self.password, salt, function(err, passwordHash) {
if (err) {
next(err);
} else {
self.password = passwordHash;
next();
}
});
}
});
}
});
I'm running into an issue when updating a particular user. Because I want to use the Model middleware, the way I'm updating a user is by using Model#findOne() followed by Model#save(). Here's the code I have to do that:
// Make sure user provided all necessary information.
if (!header.token) {
return callback(new errors.MissingHeaderDataError("Missing 'token' parameter in the header."));
} else {
// Update the user account based on what's in the envelope's body.
User.findOne({"token": header.token}, "+token +password", function (err, user) {
if (err) {
return callback(err);
} else {
// Get a list of all parameters the user wants to change.
var paramsToChange = Object.keys(body);
// Now update the parameters
paramsToChange.forEach(function(param) {
user[param] = body[param];
});
console.log("Updated user:");
console.dir(user);
user.save(function(err, user) {
if (err) {
return callback(err);
} else {
console.log("Returned user:");
console.dir(user);
User.find({}, "+token +password", function(err, foundUser) {
if (err) {
throw err;
} else {
console.log(JSON.stringify(foundUser));
}
});
callback(null, new SuccessEnvelope(user));
}
});
}
});
}
When I run my tests and come to the last bit of code (after save() is returned), I get this output:
Updated user:
{ token: '$2a$10$5VWWqjJ52aGbS4xc6NDKjuGPv8brX7pRmwiKyYjP8VHoTKCtYZiTu',
username: 'jim_bob',
password: '$2a$10$ue08HUsunzzzcbZURzXF7uaH1dZxF3SwkwadC6D1JsIC9xAUhTbCC',
email: 'joe_bob#email.com',
__v: 0 }
Returned user:
{ token: '$2a$10$fRwED..7fFFhN46Vn.ZJW..xYql5t5P39LHddjFS4kl/pmhwfT.tO',
username: 'jim_bob',
password: '$2a$10$ue08HUsunzzzcbZURzXF7uaH1dZxF3SwkwadC6D1JsIC9xAUhTbCC',
email: 'joe_bob#email.com',
__v: 0 }
[{"token":"$2a$10$5VWWqjJ52aGbS4xc6NDKjuGPv8brX7pRmwiKyYjP8VHoTKCtYZiTu","username":"joe_bob","password":"$2a$10$ue08HUsunzzzcbZURzXF7uaH1dZ
xF3SwkwadC6D1JsIC9xAUhTbCC","email":"joe_bob#email.com","__v":0}]
As you can see, the document is not properly saved to the database, as the previous data is still there. My question is: why? Why is the user not being updated when calling save? I think I'm doing everything properly, but obviously I'm not. Any help with this would be great since I'm going mad!
Apparently, in order to save a document to the database, it needs an _id. Kinda silly that Mongoose doesn't give an error when it doesn't find a document. Alas...
I updated my code to reflect the change:
// Make sure user provided all necessary information.
if (!header.token) {
return callback(new errors.MissingHeaderDataError("Missing 'token' parameter in the header."));
} else {
// Update the user account based on what's in the envelope's body.
User.findOne({"token": header.token}, "+_id +token +password", function (err, user) {
if (err) {
return callback(err);
} else {
console.log("Found user:");
console.dir(user);
// Get a list of all parameters the user wants to change.
var paramsToChange = Object.keys(body);
// Now update the parameters
paramsToChange.forEach(function(param) {
user[param] = body[param];
});
console.log("Updated user:");
console.dir(user);
user.save(function(err, user, numberTouched) {
if (err) {
return callback(err);
} else {
console.log("Returned user:");
console.dir(user);
console.log(numberTouched);
User.find({}, "+token +password", function(err, foundUser) {
if (err) {
throw err;
} else {
console.dir(foundUser);
}
});
callback(null, new SuccessEnvelope(user));
}
});
}
});
}
I have a schema and specify login is unique is true. When I use findByIdAndUpdate and pass query $set to update an user object, it did not throw back error when login is dup. Does anyone know why and how I should update an object and force schema validation?
Thanks!
// UserSchema.js
var schema = new Schema({
login: {
required: true,
unique: true
},
password: {
index: true,
type: String
}
});
// Update
UserSchema.findByIdAndUpdate('someID', { '$set': { login: 'abc' } }, function (error, user) {
callback(error, user);
});
You simply need to set runValidators to true:
findByIdAndUpdate(req.params.id, {$set: data}, {runValidators: true}, function (err, doc) {
if (err) {
// Handle validation errors
}
})
More here: http://mongoosejs.com/docs/api.html#findOneAndUpdate
Using the shorthand helper methods in Mongoose bypasses validation, so you need to use a 3 step approach:
Find
Edit
Save
For example:
// 1: Find
UserSchema.findById( 'someID',
function (err, user) {
if(!err){
// 2: Edit
user.login = 'abc';
// 3: Save
user.save(function (err, user) {
if (err) {
console.log(err);
return;
}
console.log('User saved: ' + user);
});
}
}
);