mongoose set a default field to take value of 2 other fields - mongodb

Is there a way to let one field take value of two other fields merged as default.
I have a user schema as follows:
const UserSchema = mongoose.Schema({
firstName: {
type: String,
required: true,
},
lastName: {
type: String,
required: true,
},});
I want to add a third field called fullName that defaults to merging firstName + lastName
Is that possible in mongoose?

try this :
fullName:{
type:String,
required:true,
default: function(){
return this.firstName + " " + this.lastName
}}
on doc update :
yourSchema.pre("updateOne", function (next) {
this.set({ fullName: this.get("firstName") + " " + this.get("lastName") });
next();
});

I solved this using Virtual Setters (Virtuals) as documented by Mongoose
Make sure to add this to your Schema to include virtuals when you convert a document to JSON
const opts = { toJSON: { virtuals: true } };

Related

why does this populate give me a not found function error?

How can I execute this populate so that I can get the username of the person that does the tweet? I've tried with the function getusername() but it is not working as it gives me a tweetsSchema.findOne is not a function error.
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var tweetsSchema = new Schema(
{
tweets: { type: String, required: true }, //reference to the associated book
replies: { type: String, required: false },
username: { type: Schema.Types.ObjectId, ref: 'users' }
}
);
// Virtual for bookinstance's URL
function getUsername(tweets){
return tweetsSchema.findOne({ tweets: tweets })
.populate('username').exec((err, posts) => {
console.log("Populated User " + username);
})
}
getUsername()
//Export model
module.exports = mongoose.model('tweets', tweetsSchema);
currently the function you have defined is just a function and haven't defined on the Schema of yours and not exported.
you might want to use static in mongoose
tweetsSchema.static('getUsername', async function(tweets){
return await tweetsSchema.findOne({ tweets: tweets })
.populate('username').exec((err, posts) => {
console.log("Populated User " + username);
})
})

Mongodb: Not able to add new key in nested object

I have a schema in mongodb like
var schema = new mongoose.Schema({
agentCode: String,
data: {
type: Object,
profDtl: {
education: String
}
});
Now i want to add a new property desgnName in profDtl
var schema = new mongoose.Schema({
agentCode: String,
data: {
type: Object,
profDtl: {
desgnName: String, // trying to add new property
education: String
}
});
but it is not reflected in database
I got a solution for it, whenever add new property in mongodb schema, it required a default value to reflect on new entry
for Eg:
var schema = new mongoose.Schema({
agentCode: String,
data: {
type: Object,
profDtl: {
desgnName: {
type: String,
default: ""
},
education: String
}
});
now its working fine

Unable to query sub document mongoose

I've schema like this and i', trying to get the document from the array using _id. This is my first Mongo project that I'm working, please help me how can I achieve the. I basically want to retrieve the sub document corresponds to the id and update some data in that.
var PhoneSchema = new mongoose.Schema({
type: String,
number: String
});
var StudentSchema = new mongoose.Schema({
name: String,
dept: String,
phone: [PhoneSchema]
});
var Phone = mongoose.model('Phone',PhoneSchema);
var Student = mongoose.model('Student',StudentSchema);
I've tried the following ways, but none of them are working.
Method 1: When I tried the same in the console it is giving me the parent document along with the sub document that corresponds to the phoneId
Student.findOne({"phone._id":new mongoose.Schema.Types.ObjectId(phoneId) }, {'phone.$':1}, function(err, student) {
}
Method 2: As per the mongoose documentation to retrieve sub documents, in this case I'm getting exception saying phone is undefined
Student.phone.Id(phoneId);
I've fixed this by removing Schema from the below query
Student.findOne({"phone._id":new mongoose.Types.ObjectId(phoneId) }, {'phone.$':1}, function(err, student) {
}
i tried to solve your requirement. The following code did the job.
var PhoneSchema = new mongoose.Schema({
type: String,
number: String
});
var StudentSchema = new mongoose.Schema({
name: String,
dept: String,
phone: [PhoneSchema]
});
var Phone = mongoose.model('Phone',PhoneSchema);
var Student = mongoose.model('Student',StudentSchema);
var newPhone = new Phone({
type: 'ios', number: '9030204942'
});
var newStudent = new Student({
name:'Pankaj',
dept:'cse',
phone:newPhone
});
// newStudent.save(function(err, ph) {
// if (err) return console.error(err);
// });
Student.findOne({"phone._id":mongoose.Types.ObjectId('587e6409e06170ba1708dc21') },{_id:0,phone:1}, function(err, phone) {
if(err){
console.log(err)
}
console.log(phone);
});
Find the following screenshot with result

Virtual field AND real field

Is it possible to have a virtual field that is also a field in a model?
var exampleSchema = new Schema({
name : {type: String, required: true}
slug:: {type: String}
});
exampleSchema.virtual('slug').get(function() {
if(this.slug && this.slug.length){
return this.slug;
}
return this.name.toLowerCase().replace(/ /g, '');
});
If slug is set I want to return the slug. If not, I want to return a computed value from name.
I don't want to use a static method, it needs to be a part of the result when pulled a record.
You can create a custom getter function and return the value if it exists, or the computed value if it doesn't.
var exampleSchema = new Schema({
name: {type: String, required: true}
slug: {
type: String,
get: function(value) {
if (value) {
return value;
} else {
return this.name.toLowerCase().replace(/ /g, '');
}
}
}
});

Storing values that aren't defined in the schema (dynamic schema?)

Suppose I have a Schema definition
var Users = mongoose.model('Users', new mongoose.Schema({
username: String,
salt: String,
hash: String,
facebook: {
id: String
}
}));
But I want to later
user = new Users({
username: 'myusername',
facebook: {
id: '3141592653',
displayName: 'mydisplayname' // <- wasn't in the schema ^
}
});
Then displayName simply doesn't gets stored. Is this not allowed in mongoose? Because I would imagine since MongoDB is "schema-less" there ought to be a way to do this?
You can disable the strict option on the schema to allow fields not in the schema to be saved:
var Users = mongoose.model('Users', new mongoose.Schema({
username: String,
salt: String,
hash: String,
facebook: {
id: String
}
}, { strict: false }));