I am using mongoose library for mongodb.
I am trying to save last login time with below code as suggested here.
UserModel.findOne({ email: req.body.email }, function (err, doc) {
//console.log('doc', doc);
doc.lastLoginTime = new Date();
doc.save();
});
I am unable to edit doc it stays the same. What am i missing here?
My schema is
const UserSchema = new mongoose.Schema({
email: {
type: mongoose.SchemaTypes.String,
required: true,
//unique: true,
set: toLower
},
created_at: {
type: Date,
default: Date.now
},
updated_at: {
type: Date,
default: Date.now
}
}, { strict: false });
Notice the following in the documentation on strict:
NOTE: Any key/val set on the instance that does not exist in your schema is always ignored, regardless of schema option.
You need to use doc.set():
doc.set('lastLoginTime', new Date());
Related
I have followed the mongoose docs for populating related objects, everytime authSessions is empty. I can see in mongo sessions are being populated along with the related userId field. I have tried specifying ”path” and “model” options in the populate function as well but that didn’t work either. Anyone have any ideas?
//Session.js
const SessionSchema = new mongoose.Schema({
_id: Schema.Types.ObjectId,
sessionId: { type: String, index: true },
createdDate: { type: Date, default: Date.now },
revoked: Boolean,
revokedAt: Date,
userId: {type: Schema.Types.ObjectId, ref: 'User', index: true}
})
module.exports = mongoose.models.Session || mongoose.model('Session', SessionSchema);
//User.js
const UserSchema = new mongoose.Schema({
_id: Schema.Types.ObjectId,
username: { type: String, index: true },
email: { type: String, index: true },
password: String,
registrationDate: { type: Date, default: Date.now },
authSessions: [{type: Schema.Types.ObjectId, ref: 'Session'}]
})
module.exports = mongoose.models.User || mongoose.model('User', UserSchema);
const user = await User.findById(session.userId).populate('authSessions').exec();
console.log(user) //authSessions is empty
{
_id: new ObjectId("62b6ea393e042868caa68c7d"),
username: 'asdfasdfasdf',
email: 'testaskldjflk#djlkajdf.com',
password: 'testaskldjflk#djlkajdf.com',
authSessions: [], //empty here always
registrationDate: 2022-06-25T10:58:01.709Z,
__v: 0
} ```
MongoDB, and by extension mongoose, doesn't automatically create relations for you.
If you create a Session document, you need to explicitly add it to a User document if you want populate to work:
// create a new session document and save it
const userSession = new Session(…);
await userSession.save();
// !! update the user document and save it
user.authSessions.push(userSession);
await user.save();
I have the following Schema type called Orders. I am using Arrays of SchemaTypes in some properties. When I save it to the database, it's saving everything fine. I can open the database and see all the data there.
But the problem happens in one property called "files", whenever I try to use find() or findOne() or findById(), this property always comes empty, even if I have data to show.
This is my Schemas:
const statusChildSchema = new Mongoose.Schema({
...
});
const shippingChildSchema = new Mongoose.Schema({
...
});
const fileChildSchema = new Mongoose.Schema({
path: { type: String, required: true, trim: true },
type: { type: String, required: true },
});
const ordersSchema = new Mongoose.Schema(
{
// Relationships
creator: {
type: Mongoose.Schema.Types.ObjectId,
required: true,
ref: 'Users',
autopopulate: false,
},
template: {
type: Mongoose.Schema.Types.ObjectId,
ref: 'Templates',
},
// Common
status: { type: String, trim: true, default: 'new', required: true },
// Child schemas
status_updates: [statusChildSchema],
shipping: [shippingChildSchema],
files: [fileChildSchema],
// Date properties
timings: {
created_at: { type: Date, default: Date.now, required: true },
...
},
},
{ collection: 'Orders', toJSON: { virtuals: true } }
);
Both statusChildSchema and shippingChildSchema is working normally. The problem is only with fileChildSchema. They are very similar, so I don't know what to do. I have researched in Mongoose documents and nothing helpful have been found.
This is the part of my code:
const order = await OrdersModel.findOne({
_id: orderId,
creator: userId,
});
console.log(order.files); // always printing "[]" empty array
I fixed it by installing last version of Mongoose (Version 5.11.8) and restarting everything. Looks like a bug.
I am finding a document with mongoose using findOne. I succeded in setting a property, that is not defined in the schema, to the document using doc.set(key, val). However when I want to check if the document has that property or not, it just shows no even if the document has it.
User.findOne({email: req.user.email})
.then(user=>{
if(user.posts){
//Tried with user.has("posts")=>logs error: .has is not a function
let posts = user.get("posts");
posts.push({
"Type": "Idea",
"Field/s of idea": req.body["Field/s of idea"],
"Idea": req.body.idea,
"Date": new Date()
});
user.set("posts", posts);
}else{
user.set("posts", [{
"Type": "Idea",
"Field/s of idea": req.body["Field/s of idea"],
"Idea": req.body.idea,
"Date": new Date()
}]
);
};
user.save();
})
.catch(err=>{throw err});
Schema code:
const UserSchema = new Schema({
_id: {type: ObjectId, auto: true},
username: {type: String, required: true, max:18},
email: {type: String, required: true},
password: {type: String, required: true, min:5},
date_of_registration: {type: Date, required: true}
}, { strict: false });
Schemas are fixed and not dynamic by design. If you are unsure about what type posts will be, add it to your schema and use the Mixed type.
Something like
const UserSchema = new Schema({
...
posts: [ { type: Mixed, required: false } ]
}, { strict: false });
Im using MongoDb, and I have a workspace schema with mongoose (v4.0.1):
var Workspace = new mongoose.Schema({
name: {
type: String,
required: true
},
userId: {
type: String,
required: true
},
createdOn: {
type: Date,
"default": Date.now
}
});
And a user schema:
var User = new mongoose.Schema({
email: {
type: String,
required: true,
unique: true
},
organisation: {
type: String,
required: true
},
location: {
type: String,
required: true
},
verifyString: {
type: String
},
verified: {
type: Boolean,
default: false
},
password: {
type: String,
required: true
},
createdOn: {
type: Date,
"default": Date.now
},
isAdmin: {
type: Boolean,
default: false
}
});
So the Workspace userId is the ObjectID from the User document.
When Im logged in as an adminstrator, I want to get all workspaces, as well as the email of the user that owns the workspace.
What Im doing is getting very messy:
Workspace.find({}).exec.then(function(workspaceObects){
var userPromise = workspaceObects.map(function(workspaceObect){
// get the user model with workspaceObect.userId here
});
// somehow combine workspaceObjects and users
});
The above doesnt work and gets extremely messy. Basically I have to loop through the workspaceObjects and go retrieve the user object from the workspace userId. But because its all promises and it becomes very complex and easy to make a mistake.
Is there a much simpler way to do this? In SQL it would require one simple join. Is my schema wrong? Can I get all workspaces and their user owners email in one Mongoose query?
var Workspace = new mongoose.Schema({
userId: {
type: String,
required: true,
ref: 'User' //add this to your schema
}
});
Workspace.find().populate('userId').exec( (err, res) => {
//you will have res with all user fields
});
http://mongoosejs.com/docs/populate.html
Mongo don't have joins but mongoose provides a very powerfull tool to help you with you have to change the model a little bit and use populate:
Mongoose population
You have to make a few changes to your models and get the info of the user model inside your workspace model.
Hope it helps
I have a schema:
var userSchema = new Schema({
name: String,
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
admin: Boolean,
created_at: Date,
updated_at: Date
});
Let's assume I have made 100 Users using this schema.
Now I want to change the schema:
var userSchema = new Schema({
name: String,
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
admin: Boolean,
created_at: Date,
friends: [Schema.Types.ObjectId], //the new addition
updated_at: Date
});
I need all new Users to have this field. I also want all of the 100 existing Users to now have this field. How can I do this?
You can use Mongoose Model.update to update all your documents in the collection.
User.update({}, { friends: [] }, { multi: true }, function (err, raw) {
if (err) return handleError(err);
console.log('The raw response from Mongo was ', raw);
});
I don't recommend to do it in production if the collection is big, since it is a heavy operation. But in your case it should be fine.
Using the query interface in a client app or your terminal you could do:
db.users.updateMany({
$set: { "friends" : [] }
});
Here's the docs reference.
it doesn't work for me :x
Here is my code
let test = await this.client.db.users.updateMany({
$set: { "roles" : [] }
});
and the output
{ ok: 0, n: 0, nModified: 0 }
I don't know how to do, i tried a lot of things and uh it doesn't work :'(
EDIT: I found, here is my code
await this.client.db.users.updateMany({ }, [ {$set : { "roles": []} } ]);