I have user mongoose Schema like bellow
const userSchema = new mongoose.Schema({
login: {
type: String
},
email: {
type: String
},
password: {
type: String
},
tokens: [
{
access: {
type: String
},
token: {
type: String,
}
}
],
});
I want to remove single token object, after some time, for example 30s. If I add createAt field with expires property
tokens: [
{
access: {
type: String,
required: true,
},
token: {
type: String,
required: true,
},
createdAt: {type:Date,default:Date.now,expires:10}
}
],
Then the result: all document is removed. Is there a way to do what I want?
You could do that with a post save hook.
First create a childSchema for the tokens:
ChildTokenSchema = new mongoose.Schema( {
access: {
type: String,
required: true,
},
token: {
type: String,
required: true,
},
createdAt: {type:Date,default:Date.now,expires:10}
});
Add a post-save hook on the childModel with a setTimeout:
ChildTokenSchema.post('save', function(doc) {
if (doc.createdAt && doc.createdAt.expires ) {
setTimeout(doc.remove(), doc.createdAt.expires * 1000)
}
});
Modify your parent schema:
....
....
tokens: [ChildTokenSchema]
....
Related
I have two collections in MongoDB database, Post and User. Each post contains the creator's ObjectId. When fetching all posts from the database, I want to add the name information, which is a field of User/creator. I tried to access the name field by post.creator.name, but it is not working.
const postSchema = new Schema(
{
title: {
type: String,
required: true,
},
category: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
imageUrl: {
type: String,
required: true,
},
creator: {
type: Schema.Types.ObjectId,
ref: "User",
required: true,
},
},
{ timestamps: true }
);
const userSchema = new Schema({
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
name: {
type: String,
required: true,
},
status: {
type: String,
required: true,
},
isExpert: {
type: Boolean,
required: true,
},
posts: [
{
type: Schema.Types.ObjectId,
ref: "Post",
},
],
});
exports.getPosts = (req, res, next) => {
Post.find({}).then((posts) => {
const postsWithAuthorName = posts.map(post => {
return {
...post,
name: post.creator.name
}
})
res.status(200).json({
posts: postsWithAuthorName,
});
});
};
Try this
Post.find({}).populate('creator', 'name')
See populate doc for reference.
When you query posts, creator is just an ObjectId, so you can't just call .name on it. To make it work you need to lookup this data by using e.g. populate.
I have this model.
User.js
methods: {
type: [String],
required: true,
},
local: {
email: {
type: String,
lowercase: true,
},
password: {
type: String,
},
id: Number,
title: {
type: String,
enum: ['Ms', 'Mrs', 'Mr', 'Dr'],
default: 'Mr',
},
firstName: String,
lastName: String,
role: {
type: String,
default: 'user',
},
permissions: [String],
},
status: { type: Boolean, default: true },
Please note that local field has many properties.
Say I only want to update few properties. namely title,lastName and role.
{
lastName:'virat',
role:'manager',
title:'Mr'
}
I tried to update it like this
const filter = { _id: req.params.id };
const update = {
local: {
lastName: "virat",
role: "manager",
title: "Mr",
},
};
await User.findOneAndUpdate(filter, update);
After the update, local has only 3 fields and other fields have been gone.
How do I update certain fields without losing the other fields?
Any help!
Thanks in advance! =)
Try this:
const filter = { _id: req.params.id };
const update = {
"local.lastName": "virat",
"local.role": "manager",
"local.title": "Mr"
};
await User.findOneAndUpdate(filter, update);
I've been trying updateOne, findOneAndUpdate, and update. Nothing has worked. findOne() operation returns the correct documents.
userProfileModel.updateOne(
{ userEmail },
{
$push: {
userFavLocation: payload,
},
},
(err, result) => {
console.log(err);
console.log(result);
}
);
I get this but no change in my document.
{ ok: 0, n: 0, nModified: 0 }
userEmail and payload have the correct value. When I do findOneAndUpdate, it returns correct document but won't push the value.
This is the Schem for the user profile
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const UserProfileSchema = new Schema(
{
userEmail: {
type: String,
required: true,
unique: true,
},
userProfilePictureUrl: {
type: String,
},
userSignUpDate: {
type: Date,
},
userId: {
type: String,
required: true,
unique: true,
},
userFirstName: {
type: String,
required: true,
},
userLastName: {
type: String,
required: true,
},
userGender: {
type: String,
required: true,
},
userBirthday: {
type: Date,
required: true,
},
userCoordinates: {
type: {
type: String,
default: 'Point',
},
coordinates: {
type: [Number],
},
},
userFavFacilities: {
type: Object,
},
userHometown: {
address: Object,
},
userContact: {
friends: Object,
},
userOrganizations: {
organizations: Object,
},
userMessages: {
type: Object,
},
userAlerts: {
type: Object,
},
userRoles: Object,
userFacilities: Object,
},
{ collection: 'userprofilemodels' }
);
UserProfileSchema.index({ location: '2dsphere' });
module.exports = UserProfile = mongoose.model(
'userprofilemodels',
UserProfileSchema
);
You have to add the userFavLocation field to your schema or mongoose won't perform the update.
const UserProfileSchema = new Schema(
{
userEmail: {
type: String,
required: true,
unique: true,
},
userFavLocation: [PUT_ARRAY_ITEM_TYPE_HERE],
...
}
}
In this I am using nodejs with express and mongoose. My question is how does changing the secondaryUser field affect whether or not the findOne works? If I have it as friends.id it works and it finds the right profile, but I want to tie it to the user field in the profile. If I change it to friends.user.id the findOne fails and it sends the 404 error in the catch.
router.post(
"/:handle",
passport.authenticate("jwt", {
session: false
}),
(req, res) => {
Profile.findOne({ handle: req.params.handle }).then(friends => {
const newFriend = new Friend({
initialAccepted: true,
initialUser: req.user.id,
secondaryUser: friends.id
});
newFriend
.save()
.then(Friend => res.json(Friend))
.catch(err =>
res.status(404).json({
friendnotfound: "No people found with that handle"
})
);
});
}
);
The schema used for friend is
const FriendSchema = new Schema({
initialUser: {
type: Schema.Types.ObjectId,
ref: "profile"
},
secondaryUser: {
type: Schema.Types.ObjectId,
ref: "profile"
},
initialAccepted: {
type: Boolean,
default: false
},
initialSecondary: {
type: Boolean,
default: false
},
date: {
type: Date,
default: Date.now()
}
});
This is the schema for the profile
const ProfileSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: "users"
},
handle: {
type: String,
required: true,
max: 40
},
bio: {
type: String
},
platforms: {
type: [String]
},
website: {
type: String
},
social: {
youtube: {
type: String
},
twitter: {
type: String
},
facebook: {
type: String
},
linkedin: {
type: String
},
twitch: {
type: String
}
},
games: [
{
name: {
type: String
},
platform: {
type: String
},
handle: {
type: String
},
rank: {
type: String
}
}
],
date: {
type: Date,
default: Date.now
}
});
Follow proper naming convention for variables
Profile.findOne({ handle: req.params.handle }).then(profile => { // changed name from friends to profile
const newFriend = new Friend({
initialAccepted: true,
initialUser: req.user.id,
secondaryUser: profile.id // changed name from friends to profile
// profile.user.id (ref to user table not provided in schema)
});
if you give profile.user.id the object will not get created ( checking for id inside profile schema but user id provided)
Friend Schema:
secondaryUser: {
type: Schema.Types.ObjectId,
ref: "profile" // checking for id inside profile schema
},
I am following Brad Traversy's MERN stack development course and In 4th section, I can't make post request to route localhost:5000/api/profile,
after sending post request with data as handle,status,skills which are fields in my collection, it returns error skills field required.
skills is array of strings sent from user-input.
when I checked collection-profile is created or not then it's not created and only one collection is shown as main collection user,
I followed each line of code in tutorial but getting error, I wanted to get Profile collection to be created at remote mlab mongodb,
my profile model code is
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
// Create Schema
const ProfileSchema = new Schema({
user: {
type: Schema.Types.ObjectId,
ref: "users"
},
handle: {
type: String,
required: true,
max: 40
},
company: {
type: String
},
website: {
type: String
},
location: {
type: String
},
status: {
type: String,
required: true
},
skills: {
type: [String],
required: true
},
bio: {
type: String
},
githubusername: {
type: String
},
experience: [
{
title: {
type: String,
required: true
},
company: {
type: String,
required: true
},
location: {
type: String
},
from: {
type: Date,
required: true
},
to: {
type: Date
},
current: {
type: Boolean,
default: false
},
description: {
type: String
}
}
],
education: [
{
school: {
type: String,
required: true
},
degree: {
type: String,
required: true
},
fieldofstudy: {
type: String,
required: true
},
from: {
type: Date,
required: true
},
to: {
type: Date
},
current: {
type: Boolean,
default: false
},
description: {
type: String
}
}
],
social: {
youtube: {
type: String
},
twitter: {
type: String
},
facebook: {
type: String
},
linkedin: {
type: String
},
instagram: {
type: String
}
},
date: {
type: Date,
default: Date.now
}
});
module.exports = Profile = mongoose.model("profile", ProfileSchema);
using validator.js module, I am validating input-fields,
if (Validator.isEmpty(data.skills)) {
errors.skills = "Skills field is required";
}
so, I can't find why exactly I can't find new collection as profile?
I tried using mongodb-locally, but it didn't help.
my Github repo link.
I returned user's details when route /api/users/current and changed response on success
before changing:
res.json({ msg: "Success" });
after:
passport.authenticate("jwt", { session: false }),
(req, res) => {
res.json({
id: req.user.id,
name: req.user.name,
email: req.user.email
});
}
);
Here is my commit history,
then It didn't give error as skills field is required,