I am using mongodb and I want to be able to edit a document and reinsert it WITHOUT duplicates. So far i have tried collection.findAndModify() but I couldn't get that to work. I have a collection like this:
UserProfiles = [
{
userProfileID: 1,
firstName: 'Austin',
lastName: 'Hunter',
email: 'ahun.....com',
token: '',
platform: '',
password: 'incorrect',
companyProfileID: 1,
authentication: '',
UserTopics: [
I want to be able to do this:
1 - grab the profile out of the object via searching for email match.
2 - when the email matches, edit the token and platform item.
3 - then put the document back in with no duplicates. So I can't just insert it again because that duplicates it.
Can anyone help me out on figuring this out?
Code:
function registerUser(email, token, platform) {
MongoClient.connect(url, function(err, db) {
if (err) {
console.log(err);
} else {
console.log("We are connected");
}
var collection = db.collection('UserProfile');
collection.findAndModify({
query: { email: email },
update: { token: token, platform: platform }
});
db.close();
modelname.findOneAndUpdate({ email: var_email}, { $set: { token: var_token, platform: var_platform}}, { new: true }, function(err, doc)
{
//doc here has updated document, in case you need it.
});
var_email etc. is your variable name and email is field name in
database.
{ new: true } - This part is used to fetch updated document, you can chose to not have this in your code but then you wont get updated document in response.
Related
I am having a problem with the user model that I'm using with Mongoose and MongoDB to create each profile in my database. It works fine to post one user, but throws the following error if I logout and try again:
{
"name": "MongoError",
"message": "E11000 duplicate key error collection: CourtAPIDev.users index: trackers.case_id_1 dup key: { : null }",
"driver": true,
"index": 0,
"code": 11000,
"errmsg": "E11000 duplicate key error collection: CourtAPIDev.users index: trackers.case_id_1 dup key: { : null }"
}
According to mongoose documentation: If there is more than one document (a second user) without a value for the indexed field or is missing the indexed field, the index build will fail with a duplicate key error. I don't know how to set this _id property for the trackers property –– I thought it generated automatically!
Here's the trackers part of my Schema. And the relevant case_id property, which seems to be throwing the "null" error.
The whole repository can be found on my Github here, but the likely problem spots are the ones I highlighted, I think. Here's the github link: https://github.com/KingOfCramers/node_login_with_trackers
user model:
const UserSchema = new mongoose.Schema({
email: {
type: String,
required: true,
trim: true,
minLength: 1,
unique: true,
validate: {
validator: (value) => {
return validator.isEmail(value);
},
message: '{VALUE} is not a valid email'
}
},
password: {
type: String,
required: true,
minlength: 6
},
tokens: [{
access: {
type: String,
required: true
},
token: {
type: String,
required: true
}
}],
trackers: {
tweets: [TwitterSchema],
legislation: [LegislationSchema],
court_cases: [CourtCaseSchema]
},
frequency: [EmailSchema]
});
Express route:
app.post("/users", (req,res) => {
var body = _.pick(req.body, ['email', 'password']);
body.frequency = {
alert_time: new Date(),
email: req.body.email
}
var user = new User(body);
user.save().then(() => {
return user.generateAuthToken();
}).then((token) => {
res.header("x-auth", token);
res.send(user);
}).catch((e) => {
res.status(400).send(e);
});
});
Test (mocha):
it("Should post a new user", (done) => {
var email = "uniqueemail#example.com"
var password = "9webipasd"
supertest(app)
.post("/users") // Post request to the /todos URL
.send({
email,
password
})
.expect(200)
.expect((res) => {
expect(res.headers).toIncludeKey('x-auth')
expect(res.body._id).toExist();
expect(res.body.email).toBe(email);
})
.end((err) => {
if(err){
return done(err);
}
User.findOne({email}).then((user) => {
expect(user).toExist();
expect(user.password).toNotBe(password);
done();
}).catch((e) => done(e));
});
});
My guess is that there is an index on CourtCaseSchema.case_id which does not allow duplicates.
I think you could check (in a mongo shell) that with CourtAPIDev.court_cases.getIndexes() (I think your db is named CourtAPIDev and the collection is named court_cases but I am not sure about that).
Also if you clean the test db after each run, that would explain why the tests are passing, since there is no more than one user.
Turns out, it was to do with my mongodb database, not any of my code. After searching around online, I found that if I logged into the mongo shell and then dropped all indexes from the users collection, it solved my problem. Could someone explain why this was causing my program to crash? I think it may have to do with an old user model, but I don't really understand. Thanks!
Even if you have all of your keys as unique=False, you may still get E11000 duplicate key error. So in that case, just follow these steps and check if your error is resolved.
Delete all documents from the collection (e.g. db.collection_name.deleteMany({}))
Drop the COLLECTION (NOT THE DATABASE) (e.g db.collection_name.drop())
Cheers !!
This is code of creating new user. But it does not work. In loopaback explorer everything works fine.
Participant.create({
email: `${body.login}#yandex.by`,
password: '1111',
}, function(err, user) {
console.log(user);//undefined
This code also does not work.
request.post('http://localhost:3000/api/Participants', {
form: {
email: `${body.login}#yandex.by`,
password: '1111',
},
}, function(err, user) {
console.log(user);//undefined
I am currently working on a project and I am stuck with inserting an item into an array/object in the database. What I am trying to do is to add the id of a 'upvoted' post to an array/list in the 'User' Collection, however, I cannot seem to get it to work.
The code for my schemas is as follows:
// this is a child scheme/sub-document
var uvpSchema = new Schema();
uvpSchema.add({
post: String
});
var dvpSchema = new Schema();
dvpSchema.add({
post: String
});
//main schema
var userSchema = new Schema({
firstname: { type: String, required: true },
lastname: { type: String, required: true },
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
upVotedPosts: [uvpSchema],
downVotedPosts: [dvpSchema],
created_at: Date,
});
And here is the code in my 'routes.js' to insert the id of the post into the array:
var newPush = {
post: postID // postID is a variable that I have already defined
};
User.findOneAndUpdate({username: req.session.user}, {$push: {upVotedPosts: newPush}}, {upsert: true, save: true}, (err, user) => {
if (err) console.log(err);
user.upVotedPosts.push(newPush);
User.save;
res.redirect(req.get('referer'));
console.log(user.upVotedPosts);
});
The error I receive in my terminal is:
{ _id: 595f68b5fadd49105813f8a4 },{ _id: 595f693d3c2c21189004b0a7 },{ _id: 595f70a2df80e0252894551b }
events.js:163
throw er; // Unhandled 'error' event
^
Thanks in advance ;-)
Route.js
User.findOneAndUpdate({username: req.session.user}, {$push: {upVotedPosts: newPush}}, {upsert: true, save: true}, (err, user) => {
if (err) console.log(err);
user.upVotedPosts.push(newPush);
User.save;
res.redirect(req.get('referer'));
console.log(user.upVotedPosts);
});
You dont need to explicitly push, since you pushed using findOneandUpdate - $push
Refer here
Secondly , its
user.save()
and not
User.save
First of all, I'd like to thank everyone's' help ;-)
I finally managed to get it partially working! My problem was that my functions were running asynchronously, causing some problems. I solved this by adding callback functions to each mongoose function.
However, the same error is still being returned, causing the server to crash. Everything else works; the new item is added to the array.
Is there anyway to ignore the error so that the server doesn't crash?
I would like to insert data at Meteor's startup. (And after from a JSON file)
At startup, I create a new account and I would like to insert data and link it to this account once this one created.
This is the code that creates the new account at startup:
if(!Meteor.users.findOne({emails: { $elemMatch: { address: "test#test.com"}}})){
var id = Accounts.createUser({ email: "test#test.com", password: "1234", profile: { name: 'Test' } });
Meteor.users.update({_id: id }, { $set: { admin: false }});
}
And after that, I need to insert data and link it to this account with its ID. (In different collections).
So I tried to do something like that, but obviously It didn't work:
UserData = new Mongo.Collection('user_data');
if(!Meteor.users.findOne({emails: { $elemMatch: { address: "test#test.com"}}})){
var id = Accounts.createUser({ email: "test#test.com", password: "1234", profile: { name: 'Test' } });
Meteor.users.update({_id: id }, { $set: { admin: false }});
UserData.insert({
createdBy: id,
firstname: "test",
/* ... */
});
}
EDIT
Sorry for not have been clear.
The real issue is the :
UserData = new Mongo.Collection('user_data');
declaration is in another file, so I can't do like above.
As it's not in the same file, I tried to get the userId that got "test#test.com" as the email (the account's email created at startup). And once I got it, I want to use it in "createdBy: ID_HERE".
Ok, you'll want to check out Structuring your application. You'll have to make the file with the definition load earlier, or the one with the fixture later.
Normally you have your collections inside lib/ and your fixtures inside server/fixtures.js.
So if you put your insert code into server/fixtures.js it'll work.
I have a MongoDb schema like this
var User = new Schema({
"UserName": { type: String, required: true },
"Email": { type: String, required: true, unique: true },
"UserType": { type: String },
"Password": { type: String }
});
I am trying to create a new user
This is done in NodeJs using mongoose ODM
And this is the code for creating:
controller.createUser = function (req, res) {
var user = new models.User({
"UserName": req.body.UserName.toLowerCase(),
"Email": req.body.Email.toLowerCase(),
"UserType": req.body.UserType.toLowerCase()
});
models.User.findOne({ 'Email': user.Email }, function (err, olduser) {
if (!err) {
if (olduser) {
res.send({ 'statusCode': 409, 'statusText': 'Email Already Exists' });
}
else if (!olduser) {
user.setPassword(req.body.Password);
user.save(function (err, done) {
if (!err) {
console.log(user);
res.send({ 'statusCode': 201, 'statusText': 'CREATED' });
}
else {
res.send({ 'Status code': 500, 'statusText': 'Internal Server Error' });
}
});
}
}
else {
res.send({ 'statusCode': 500, 'statusText': 'ERROR' });
}
});
};
The for creating new user,I am giving attributes and values as follows:
{
"UserName": "ann",
"Email": "ann#ann.com",
"UserType": "normaluser",
"Password":"123456"
}
And I am getting error like this:
{"Status code":500,"statusText":"Internal Server Error","Error":{"name":"MongoError","err":"E11000 duplicate key error index: medinfo.users.$UserName_1 dup key: { : \"ann\" }","code":11000,"n":0,"connectionId":54,"ok":1}}
I understand that this error is because UserName is duplicated ,but I haven't set UserName with unique constraint.Whenever I add a new row,I need only email to be unique,UserName can be repeated.How to achieve this??
#ManseUK Is probably right, that looks like UserName is a 'key' - in this case an index. The _id attribute is the "primary" index that is created by default, but mongodb allows you to have multiple of these.
Start a mongo console and run medinfo.users.getIndexes()? Something must have added an index on 'UserName'.
required: true wouldn't do that, but you might have played with other settings previously and the index hasn't been removed?
There should be an index that is blocking.
You can try the db.collection.dropIndex() method
medinfo.users.dropIndexes()
I got the similar issue on my project. I tried to clear out all the documents and the dup issue still keep popping up. Until I dropped this collection and re-start my node service, it just worked.
What I had realized is that my data-structures were changing -- this is where versioning comes in handy.
You may need to get a mongoose-version module, do a thing.remove({}, ...) or even drop the collection: drop database with mongoose
I use RoboMongo for an admin tool (and I highly recommend it!) so I just went in and right-clicked/dropped collection from the console.
If anyone knows how to easily version and/or drop a collection from within the code, feel free to post a comment below as it surely helps this thread ( and I :) ).