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

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 }));

Related

Is there a way to convert a date value to a User's timezone in Mongoose?

I have searched everywhere, StackOverflow and else where but I can't seem to find a fix for my problem. I have a mongoose schema like this:
// user.model.js
const mongoose = require('mongoose');
const User = new Schema({
firstName: String,
lastName: String,
tz: String,
registrationDate: {
type: Date,
default: Date.now(),
}
})
And I have a controller which creates a User like this:
// user.controller.js (async)
let user = await User.create({
'firstName': 'John',
'lastName': 'Doe',
'tz': 'Africa/Kampala'
});
await reply.send(user); // I am using Fastify framework
No matter what I do, when the User is returned it always gives the UTC time and not the time that the User actually is in. have tried using Mongoose transform:
// Transform on the schema
const moment = require('moment-timezone');
const User = new Schema({
// Schema definitions
}, {
toJSON: {
transform: function (doc, ret) {
ret.registrationDate= moment.tz(doc.registrationDate, doc.tz).format();
return ret;
}
}
})
And have also tried using get like this:
const User = new Schema({
// Other definitions
registrationDate: {
type: Date,
default: Date.now(),
get: convertDate
}
})
function convertDate(registrationDate) {
return moment.tz(registrationDate, this.tz).format()
}
But no luck. I would appreciate any assistance or guidance in getting this to work on the model. Thanks!

Mongoose distinct returns empty array

I have the following schema and query. I'm trying to retrieve all tags in my document by using the .distinct() method but that's not working. Any suggestions would be great.
const postingSchema = new mongoose.Schema({
time: String,
date: String,
company: String,
position: String,
description: String,
tags: Array,
});
router.get('/tags', async function(req, res){
const tags = await Postings.find({}).distinct("tags").exec();
if(!tags){
return res.status(404).json({message: "No Tags!"});
}
return res.status(200).json(tags);
}

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

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 } };

How to find parent document?

This is my 2 schemas:
var activationTokenSchema = new Schema({
token: String,
});
var userSchema = new Schema({
name: String,
login: String,
email: String,
password: String,
balance: Number,
isActivated: Boolean,
activationToken: { type: Schema.Types.ObjectId, ref: 'ActivationToken' }
});
const User = mongoose.model('User', userSchema);
const ActivationToken = mongoose.model('ActivationToken', activationTokenSchema);
User is parent model, which has child model ActivationToken.
Having only token string, how can I find User document?
Or is it better to redesign ActivationTokenSchema and include userId there, so only child will be pointing to parent?

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