MongoDB Chat Schema - javascript

Im trying MongoDB and as a matter of starting point im creating a schema for a chat application that may be simple to scale in the future, so im wondering if this looks correct from what i have been seeing in the docs. So far i have 3 collections User, Room, Message. Also i would need to perform some queries like getting all messages from a sepecific room, get all messages from a specific user, etc
Designed with mongoose:
var user = new mongoose.Schema({
username: { type: String, lowercase: true, unique: true },
email: { type: String, lowercase: true, unique: true },
password: String,
is_active: { type: Boolean, default: false },
});
var room = new mongoose.Schema({
name: { type: String, lowercase: true, unique: true },
topic: String,
users: [user],
messages: [message],
created_at: Date,
updated_at: { type: Date, default: Date.now },
});
var message = new mongoose.Schema({
room: room,
user: user,
message_line: String,
created_at: { type: Date, default: Date.now },
});
var User = mongoose.model('User', user);
var Room = mongoose.model('Room', room);
var Message = mongoose.model('Message', message);

//message model
'use strict';
import mongoose from 'mongoose';
var Schema = mongoose.Schema;
var ObjectId = Schema.Types.ObjectId;
var MessageSchema = new Schema({
send: {
type: ObjectId,
ref: 'User',
required: true
},
message: {
type: String,
required: true
},
date: {
type: Date
},
created_by: {
type: ObjectId,
ref: 'User',
required: true
},
thread: {
type: ObjectId,
ref: 'MsgThread',
required: true
},
is_deleted: [{
type: ObjectId,
ref: 'User'
}]
}, {
timestamps: {
createdAt: 'created_at',
updatedAt: 'last_updated_at'
}
});
export default mongoose.model('Message', MessageSchema);
//dont use rooms,,use thread like groupchat or personalChat
import mongoose from 'mongoose';
var Schema = mongoose.Schema;
var ObjectId = Schema.Types.ObjectId;
const s3 = require("../../utils/s3");
var MsgThreadSchema = new Schema({
users: [{
type: ObjectId,
ref: 'User'
}],
group_name: {
type: String
},
created_by: {
type: ObjectId,
ref: 'User'
},
community: {
type: ObjectId,
ref: 'Community'
},
image_url: {
type: String
}
}, {
timestamps: {
createdAt: 'created_at',
updatedAt: 'last_updated_at'
}
});
export default mongoose.model('MsgThread', MsgThreadSchema);

Related

NodeJs How can i show first 3 authors in my model?

I made a simple api. With 3 tables.(collections with mongodb). Like Collections-Authors-Articles. I want to show 3 author on collections but i cant found how can i do it ? When i send get request to collections on postman i need to see like;
"name":xxx;
"icon":xxx;
"authors":{
authorid,
authorid,
authorid }
My Schemes :
article.js =
const { db } = require("../collection");
const mongoose = require("mongoose"),
Schema = mongoose.Schema;
var Articles = Schema({
author: {
type: Schema.Types.ObjectId,
ref: "Authors",
},
collectionid: {
type: Schema.Types.ObjectId,
ref: "Collections",
},
name: {
type: String,
required: true,
},
content: {
type: String,
required: true,
},
createddate: {
type: Date,
default: Date.now,
},
updateddate: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model("Articles", Articles);
author.js =
const mongoose = require("mongoose"),
Schema = mongoose.Schema;
var Authors = Schema({
name: {
type: String,
required: true,
},
avatar: {
type: String,
required: true,
},
});
module.exports = mongoose.model("Authors", Authors);
collections.js =
const mongoose = require("mongoose"),
Schema = mongoose.Schema;
var Collections = Schema({
name: {
type: String,
required: true,
},
icon: {
type: String,
required: true,
},
});
module.exports = mongoose.model("Collections", Collections);
You can use populate to populate collection authors, see the mongoose docs

Mongoose getting the error: MissingSchemaError: Schema hasn't been registered for model

I am getting this error and can't figure it out. I HAVE NAMED THE REF EXACLTY AS THE MODEL:
MissingSchemaError: Schema hasn't been registered for model "ParticipantStatus".
Here are my models:
ParticipantStatus model:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const participantStatusSchema = new Schema({
_id: {
type: Number,
required: true,
},
name: {
type: String,
required: true,
},
});
module.exports = mongoose.model('ParticipantStatus', participantStatusSchema);
EventParticipant model:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const eventParticipantSchema = new Schema(
{
userId: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true,
},
eventId: {
type: Schema.Types.ObjectId,
ref: 'Event',
required: true,
},
teamId: {
type: Schema.Types.ObjectId,
ref: 'Team',
},
statusId: {
type: Number,
ref: 'ParticipantStatus',
required: true,
},
isActive: {
type: Boolean,
required: true,
default: true,
},
},
{ timestamps: true }
);
module.exports = mongoose.model('EventParticipant', eventParticipantSchema);
This is the code where the error is thrown, when i try to get event participants and populate statusId(ParticipantStatus):
let participants = await EventParticipant.find(
{
eventId: req.params.eventId,
isActive: true,
},
{ _id: false }
)
.populate('userId', 'email')
.populate('statusId')
.select('userId');
I have been stuck for hours on this. Only the .populate('statusId') part throws the error, the rest works well. Thanks in advance
type of field that you want to populate based on should be ObjectId so change the type of statusId from Number to Schema.Types.ObjectId like this:
statusId: {
type: Schema.Types.ObjectId,
ref: 'ParticipantStatus',
required: true,
}
Well the problem was that u need to import:
const ParticipantStatus = require('../models/participantStatus.model');
even if you do not REFERENCE IT DIRECTLY in your code, which is really strange in my opinion.
Hope this helps anyone.

What is the best way to attach properties to mongoose documents

I have an array of posts and each post contains an author id. I want to loop through each post and find author from User model by using author id and then attach it to post. What is the best and efficient way to do it. I am currently doing it this way, but it decreases the performance. Thanks.
posts = await Promise.all(
posts.map(async post => {
post.author = await User.findById(post.author).lean();
return post;
})
);
// POST SCHEMA
const postSchema = new mongoose.Schema({
author: {
type: String,
required: true
},
body: {
type: String,
required: true
},
post_image: {
url: String,
public_id: String,
width: Number,
height: Number
},
date_created: {
type: Date,
default: Date.now()
}
});
// USER SCHEMA
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
register_date: {
type: Date,
required: true,
default: Date.now()
},
friends: {
type: Array,
default: []
}
});
// NEW POST SCHEMA
const postSchema = new mongoose.Schema({
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users',
required: true
},
body: {
type: String,
required: true
},
post_image: {
url: String,
public_id: String,
width: Number,
height: Number
},
date_created: {
type: Date,
default: Date.now()
}
});
// USER SCHEMA
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
register_date: {
type: Date,
required: true,
default: Date.now()
},
friends: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'users',
required: true
}],
});
You can use auto population of mongo object in mongoose. It won't cause performance issues as it uses id index. Similar to this doc: https://mongoosejs.com/docs/populate.html
Your query will look like this:
const post = await Post.find({ author: { $in: req.user.friends }})
.populate('author')
.exec();
console.log(post);
Or you can use aggregate according to this document: https://mongoosejs.com/docs/api/aggregate.html
Your query will then look like:
const query = [
{ $match: { author: { $in: req.user.friends } } },
{ $lookup: { from: "users", localField: "author", foreignField: "_id", as: "authorDetails" } },
{ $unwind: "authorDetails" },
]
const post = await Post.aggregate(query).exec();
console.log(post);

Updating count of individual sub document that's in an array of a mongo document

So the example right now is for the User table.. I have a UserWeapon document embedded that is an array of all the weapon's a user has and how many kills they have with the weapon. I want to write a query that when given the userId, weaponId, and new kills, it'll update the sub document accordingly.
So something like
const user = await User.findById(userId);
const userWeapon = await user.userWeapon.findById(weaponId);
userWeapon.kills = userWeapon.kills + newAmmountOfKills
user.save();
What would be the most efficient way to do this?
Schemas:
const UserWeaponSchema = new Schema({
weapon: { type: Schema.Types.ObjectId, ref: 'Weapon' },
user: { type: Schema.Types.ObjectId, ref: 'User' },
kills: {
type: Number,
required: true,
unique: false,
},
deaths: {
type: Number,
required: true,
unique: false
},
equippedSkin: {
type: Schema.Types.ObjectId, ref: 'WeaponSkin',
required: false,
},
ownedWeaponSkins: [{ type: Schema.Types.ObjectId, ref: 'WeaponSkin'}]
});
const UserSchema = new Schema({
username: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
weapons: [{
type: Schema.Types.ObjectId, ref: 'UserWeapon'
}],
});
You can use $inc operator and run update operation, something like:
UserWeaponSchema.update({ weapon: weaponId, user: userId }, { '$inc': { 'kills': newAmmountOfKills } })

I am getting E11000 duplicate key error collection: restauracja.tables index: reservations.user.email_1 dup key: { : null }

This is my Table Collection:
const tableSchema = new Schema({
number: {
type: Number,
required: true,
unique: true
},
seats: {
type: Number,
required: true
},
reservations: [orderSchema]
})
const Table = mongoose.model('Table', tableSchema)
And OrderSchema:
const orderSchema = new Schema({
time: {
type: String,
required: true
},
date: {
type: String
},
user: userSchema
})
And User Collection and Schema:
const userSchema = new Schema({
firstname: {
type: String,
required: true
},
lastname: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
phone: {
type: String
},
password: {
type: String,
required: true
},
admin: {
type: Boolean,
default: false,
required: true
}
})
const User = mongoose.model('User', userSchema)
When i would like to create the second (i have no idea why first is adding) instance of table, i am getting error like in title:
MongoError: E11000 duplicate key error collection: restauracja.tables index: reservations.user.email_1 dup key: { : null }
I can create only one document in table, but i have different values in the second one.

Categories

Resources