Sub-document validation receives array of documents - mongodb

I have a Parent schema (Dashboard) that contains children (Widget).
The problem is that I need to validate single widget, but .pre('save') receives array of widgets.
Is there any way to validate single property? I tried to add widgetSize: { type: String, validate: xxx }, but with no luck.
var widgetSchema = new Schema({
_id: Schema.Types.ObjectId,
measurement: { type: String, required: true },
type: { type: String, required: true },
key: { type: String, default: '' },
background: { type: Schema.Types.Mixed, default: false },
localeId: { type: Schema.Types.Mixed, default: false },
hintText: String,
widgetSize: { type: String }
});
widgetSchema.pre('save', function (next) {
console.log(this);
if(!sizeValidator(this.widgetSize)) {
return next(new Error('Size format was incorrect: ' + this.widgetSize));
}
next();
});
var dashboardSchema = new Schema({
slug: { type: String, required: true },
name: { type: String, required: true },
backgroundImage: String,
defaultDashboard: { type: Boolean, default: false },
backgroundColor: String,
widgets: [widgetSchema]
});
The code to add a sub-documents
dashboard.widgets.push(widgetToCreate);
return dashboard.saveAsync(); // promisified

It looks like you were using this to validate the subdoc value which as you noticed is set to the top level document. More directly, you can use the value passed to the validate function like so:
var widgetSchema = new Schema({
_id: Schema.Types.ObjectId,
measurement: {
type: String,
required: true
},
type: {
type: String,
required: true
},
key: {
type: String,
default: ''
},
background: {
type: Schema.Types.Mixed,
default: false
},
localeId: {
type: Schema.Types.Mixed,
default: false
},
hintText: String,
widgetSize: {
type: String,
validate: function widgetSizeValidate(val) {
return val === 'foobar';
}
}
});

Related

Mongodb mongoose join two collection and fetch data

schema:
var UserSchema = new Schema({
id: { type: String, unique: true },
username: { type: String, unique: true },
password: String,
first_name: String,
last_name: String,
email: { type: String, unique: true },
phone: { type: String, unique: true },
status: { type: Boolean, default: false },
role: {
type: String,
enum: ["REGULAR", "ADMIN", "SUPER-ADMIN", "OPERATOR"],
default: "REGULAR",
},
tenantRef: { type: Schema.Types.String, ref: "tenant" },
teamRef: { type: Schema.Types.String, ref: "team" },
customerRef: { type: Schema.Types.String, ref: "customer" },
created: { type: Date, default: Date.now },
});
var CustomerSchema = new Schema({
id: { type: String, unique: true },
name: String,
plan: String,
billing: String,
status: { type: Boolean, default: true },
created: { type: Date, default: Date.now },
});
controller:
userController.getUsers = async function (req, res) {
const users = await UserSchema.find({}).populate({
path: "teamRef",
});
console.log(users);
return res.status(200).send(users);
};
Here i am trying to join user and customer so that i can get customer name along with user data .
I am using above way but it is not working.
Please take a look how can i do it

how to create nested schema in nestjs use mongodb

email
password
role
confirmed
id
address
city
street
My user schema should be like this. I want it to appear as a nested schema. separate the address space.
export const UserSchema = new mongoose.Schema({
email: { type: String, unique: true, required: true },
password: { type: String, required: true },
role: { type: String, enum: Role, default: Role.USER },
confirmed: { type: Boolean, default: false },
id: { type: String, default: uuid.v4 },
});
UserSchema.pre('save', async function (next) {
try {
if (!this.isModified('password')) {
return next();
}
const hashed = await bcrypt.hash(this['password'], 10);
this['password'] = hashed;
return next();
} catch (err) {
return next(err);
}
});
interface user
export interface User extends Document {
id:string;
email: string;
password: string;
role: Role[];
address: ?
}
I have to add the address in user. How?
export const AddrSchema= new mongoose.Schema({
city: { type: String, default: "bb" },
street: { type: String, default: "aa" },
})
I think this will solve it.
export const UserSchema = new mongoose.Schema({
email: { type: String, unique: true, required: true },
password: { type: String, required: true },
role: { type: String, enum: Role, default: Role.USER },
confirmed: { type: Boolean, default: false },
id: { type: String, default: uuid.v4 },
address: {
city: { type: String, default: "bb" },
street: { type: String, default: "aa" },
}
});

MongoDB/Mongoose Schema for checking room availability

I've following schema for a Hotel room.
const { Schema, model } = require('mongoose');
const reservationSchema = new Schema({
checkIn: {
type: Date,
require: true
},
checkOut: {
type: Date,
require: true
},
status: {
type: String,
require: true,
enum: ['pending', 'cancel', 'approved', 'active', 'completed']
}
});
const roomSchema = new Schema(
{
title: {
type: String,
required: true
},
slug: {
type: String
},
description: {
type: String,
required: true
},
capacity: {
adults: {
type: Number,
required: true
},
childs: {
type: Number,
default: 0
}
},
roomPrice: {
type: Number,
required: true
},
gallery: [
{
type: String,
require: true
}
],
featuredImage: {
type: String,
require: true
},
reservations: [reservationSchema],
isAvailable: {
type: Boolean,
default: true
},
isFeatured: {
type: Boolean,
default: false
},
isPublish: {
type: Boolean,
default: false
}
},
{ timestamps: true }
);
module.exports = model('Room', roomSchema);
Now I want to find rooms which are not reserved for a particular date period.
Example: If the search query is checkIn: 12/25/2019 and checkOut:12/30/2019 then the query result will show that rooms which are not reserved for this period. Also, it will show the reserved room if the reservation status is canceled.
How can I achieve this?
Do I need to change the Schema design for achieving this?

how to search for any value in the document

I want to search for all value present without specifying key explicitly. Is it possible with this type of schema? If so, how can I write my query. I tried to write query with other refs but I am unable to write without specifying key for each.
const pschema = new Schema({
user: {
type: Schema.Types.ObjectId, // combine by id
ref: "users" //existing model reference
},
company: {
empNo: {
type: Number,
required: true
},
status: {
type: String,
required: true
},...
},
personal: {
gender: {
type: String
},
dob: {
type: Date
},...
},
skills: {
type: [String],
required: true
},
experience: [
{
title: {
type: String,
required: true
},
company: {
type: String,
required: true
},
location: {
type: String
}...
}
],
education: [
{
school: {
type: String,
required: true
},
degree: {
type: String,
required: true
},
specialization: {
type: String
},..
}
],
social: {
twitter: {
type: String
},
facebook: {
type: String
},
linkedin: {
type: String
},...
}
});
For example: If i give linkedin url if should search in social-linkedin and same if i give c it should search in skills array

MongoDB (mongoose) about refs

who can explain with example how to get from another schema user data (for example useravatar)
while i read about refs and i cant understand.
This is my code, but i want to send back not only article but with profile datas about author. How can i do this ? I have authorID already for this.
router.post('/get-article', (req, res) => {
const { id, authorID } = req.body.data;
Article.findByIdAndUpdate({ _id: id }, { $inc: { "pageview": 1 } }, (err, article) => {
if (err) return res.status(400).json({ NotFound: "Article Not Found" })
res.json({ article })
})
})
article schema
const schema = new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
title: { type: String, required: true },
image: { type: String, required: true },
content: { type: String, required: true },
email: { type: String, required: true },
author: { type: String, required: true, index: true },
added: { type: Date, default: Date.now },
pageview: { type: Number, default: 0 }
});
User schema
const schema = new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
username: { type: String, required: true },
email: { type: String, required: true },
facebookId: { type: String },
githubId: { type: String },
googleId: { type: String },
useravatar: { type: String, required: true },
userip: { type: String, required: true },
accessToken: { type: String },
date: { type: Date, default: Date.now }
});