Hey when i was using firebase it was kind of easy to update or add a subcollection , but its confusing in mongodb ! i see people adding arrays instead of subcollection but what if i want to add an element to that existing array ! how can it be done , or how to add something like subcollection !
here is my example !
Model :
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
passwordHash: {
type: String,
required: true,
},
phone: {
type: String,
required: true,
},
isAdmin: {
type: Boolean,
default: false,
},
street: {
type: String,
default: "",
},
apartment: {
type: String,
default: "",
},
zip: {
type: String,
default: "",
},
city: {
type: String,
default: "",
},
country: {
type: String,
default: "",
},
});
exports.User = mongoose.model("User", userSchema);
I want to add a notification collection or document to this User model whenever he recieves one ? i want the notifications to be a collection with documents referring the each notification ! but i didn't know how to do it !
Related
so i'm trying ref a array of daysOff (Ferias model) as a fiel in a User model,
i'm new to MongoDB and mongoose, and i'm trying to build a API that manages a company workers days off.
I apologyse in advance for the "format" of this question but it's the very first time that I post a question in StackOverflow :)
Thanks u all!
const mongoose = require("mongoose");
const moment = require("moment");
const feriasSchema = mongoose.Schema(
{
user: {
type: mongoose.Types.ObjectId,
required: true,
ref: "User",
},
firstName: {
type: String,
ref: "User",
},
lastName: {
type: String,
ref: "User",
},
workerNumber: {
type: Number,
ref: "User",
},
sectionOfWork: {
type: String,
ref: "User",
},
totalFerias: {
type: Number,
required: true,
},
//this is the field i want to add in User model as an array of (dates format DD/MM/YYYY)
ferias: {
type: [String],
//default: [Date],
required: true,
},
tipoFerias: {
type: String,
required: true,
},
modo: {
type: String,
required: true,
},
},
{ timestamps: true }
);
module.exports = mongoose.model("Ferias", feriasSchema);
// USER MODEL
const userSchema = mongoose.Schema(
{
firstName: {
type: String,
required: true,
},
lastName: {
type: String,
required: true,
},
email: {
type: String,
required: [true, "Please enter a valid email address"],
unique: true,
},
password: {
type: String,
required: [true, "Please enter a password"],
},
workerNumber: {
type: Number,
required: true,
unique: true,
},
sectionOfWork: {
type: String,
required: true,
},
chefia: {
type: String,
required: true,
},
//this is the field i want to be an array (from Ferias model)
ferias: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Ferias",
}],
role: {
type: String,
required: true,
},
},
{ timestamps: true }
);
module.exports = mongoose.model("User", userSchema);
what am i doing wrong?
i'm getting and empty array ...
in express I can send the questioned data separately but u want to send a json to some frontend with all the fields of a user, with the "ferias" array present.
I want to join two schemas into one because they both have almost same attributes and i want to use it for PostSchema that a user and also an owner can create and show their posts but i dont know how to achieve it
for example :
UserSchema
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
gender: String,
role: {
type: String,
default: "User",
},
});
OwnerSchema
const OwnerSchema = new mongoose.Schema({
name: String,
gender: String,
email: String,
password: String,
role: {
type: String,
default: 'Owner'
},
restaurant: RestaurantSchema
})
PostSchema
const PostSchema = new mongoose.Schema({
title: {
type: String,
required: true,
},
body: {
type: String,
required: true,
},
photo: {
type: String,
required: true,
},
postedBy: {
type: ObjectId,
ref: *Combined user and owner*,
},
comments: [CommentSchema],
}, { timestamps: true });
Get rid of your OwnerSchema - and modify your UserSchema to something like the below:
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
gender: String,
role: {
type: String,
default: "User", //could be Owner when applicable
},
restaurant: RestaurantSchema, //could be null when role=User
});
was wondering if someone had an of how I can develop a schema for the following model below, all fields are required.
Data I want captured
{
"name": "The Shop",
"address": {
"line_one":"123 Joe Blogs Ave",
"line_two":"District 1",
"city":"Random city",
"postcode/zip":"AB12 3BJ"
},
"coverImage":"imageURL",
"rating": 4.5
}
const placeSchema = mongoose.Schema({
name: {
type: String,
required: true,
address: {
line_one: {
type: String,
required: true,
},
line_two: {
type: String,
required: true,
},
city: {
type: String,
required: true,
},
postcode: {
type: String,
required: true,
},
},
},
coverImage: {
type: String,
rating: {
type: mongoose.Types.Decimal128,
},
},
});
When posting the data I only find returned the name, coverimage, _id and __v.
You would use subdocuments for this, or Nested Schemas:
So basically for nested Objects you define another Schema, and then tell the main schema that the field is of type subschema
const addressSchema = mongoose.Schema({
line_one: {
type: String,
required: true,
},
line_two: {
type: String,
required: true,
},
city: {
type: String,
required: true,
},
postcode: {
type: String,
required: true,
}
})
const placeSchema = mongoose.Schema({
name: {
type: String,
required: true,
address: {
type: addressSchema,
required: true
}
},
coverImage: {
type: String,
rating: {
type: mongoose.Types.Decimal128,
},
},
});
```
I am new to the backend and trying to learn by building some stuff but unfortunately, I got stuck.
I want to know if I can update a nested array of objects in Users Schema using Mongoose in an efficient and elegant way.
Users Schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const UserSchema = new Schema({
name: {
type: String,
required: true
},
username: {
type: String,
required: true,
unique: true
},
email: {
type: String,
required: true,
unique: true
},
gender: {
type: String,
required: true
},
password: {
type: String,
required: true
},
friends: [{}],
notifications: []
}, {timestamps: true});
module.exports = User = mongoose.model('user', UserSchema);
In the friends' field, I stored friend request with the status of pending
I want if the user whose the request was sent to, hits an endpoint, to accept the request
by changing the status from pending to success.
This is how a friend request was stored:
friendRequest = {
_id: req.user.id,
status: 'pending',
sentByMe: false,
new: true,
inbox: []
}
Thanks as you help me out!!! 🙏🙏🙏
You should first create an additional friendRequest and inbox schemas like this:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const InboxSchema = new Schema({
user_id: {
type: String,
required: true
},
from_id: {
type: String,
required: true
},
message: {
type: String,
required: true
},
the_date_time: {
type: Date,
required: true
}
});
mongoose.model('Inbox', InboxSchema);
const FriendRequestSchema = new Schema({
user_id: {
type: String,
required: true
},
status: {
type: String,
required: true
},
sentByMe: {
type: Boolean,
required: true,
unique: true
},
inbox: [InboxSchema]
})
mongoose.model('FriendRequests', FriendRequestSchema);
and update your Users schema:
const UserSchema = new Schema({
name: {
type: String,
required: true
},
username: {
type: String,
required: true,
unique: true
},
email: {
type: String,
required: true,
unique: true
},
gender: {
type: String,
required: true
},
password: {
type: String,
required: true
},
friends: [FriendSchema],
notifications: [FriendRequestSchema]
}, {timestamps: true});
And then use the friendRequest object
friendRequest = {
_id: req.user.id,
status: 'pending',
sentByMe: false,
new: true,
inbox: []
}
to update the Users collection
Users.update({ _id: user_id }, { $push: { notifications: friendRequest } });
Whenever you have arrays of objects within collections, its best to define additional schemas. You should also consider adding indexes to your collection schemas.
Update:
A FriendSchema would look like this:
const FriendsSchema = new Schema({
friend_id: {
type: String,
required: true
},
friend_name: {
type: String,
required: true
},
friendship_made: {
type: Date,
required: true
}
// you have to define FriendSchema before you define Users since you
// now reference [FriendSchema] in UserSchema
mongoose.model('Friends', FriendSchema);
And so is personA friends with personB?
Users.findOne({ "_id": personA.id, "friends.friend_id": personB.id});
I'm having problems accessing user.info.name.familyName in a query. I'm newish to database design and queries and I don't know if its possible.
So here is the schema I have. Perhaps it might need to be redesigned for what I'm trying to do to work.
var UserSchema = mongoose.Schema({
username: {
type: String,
index: true,
required: true,
unique: true
},
password: {
type: String,
required: true
},
email: {
type: String,
required: true,
lowercase: true
},
emailVerified: {
type: Boolean,
default: false
},
info: {
name: {
givenName: String,
familyName: String,
},
address: {
street: String,
city: String,
state: String,
zipCode: String
},
primaryPhone: String,
cellPhone: String,
website: String,
licenseNumber: String,
title: String,
company: String
},
avatar: {
type: String,
default: '/images/avatar/default/contacts-128.png'
},
friends: [{ type: ObjectId, ref: User }],
friendRequests: [{ type: ObjectId, ref: User }]
});
I have a search function that currently searches by username or email and works fine, but I'd like it to also search by the users givenName or familyName. Here is the search function...
module.exports.search = function(searchValue, callback) {
var searchValue = new RegExp(`^${searchValue}`, 'i');
var query = {
$or: [
{username: searchValue},
{email: searchValue}
// {givenName condition here...}
]
}
User.find(query, callback).limit(10);
}
I tried this... and it didn't work
{info.name.givenName: searchValue}
I tried a few other nonsensical things but they also failed...
So to summarize my question, how would I either restructure the schema or query to be able to check the searchValue against user.info.name.givenName?
This way:
{'info.name.givenName': searchValue}
notice the quotes.
You were close :)