How to add an array as different objects mongodb - node.js

I'm having some trouble with a post function in nodeJs
I have the next body to post:
{
"_id": "fffff-ggg-jjjjj",
"type": "",
"gamers": [
"Raul Andres",
"Pedro",
"Juan"
]
}
(I shouldn't change the post body)
And this is my Schema:
var gameSchema = new Schema({
_id: {
type: String,
required: true,
trim: true
},
type: {
type: String,
trim: true
},
gamers: [{
name: {
type: String,
required: true,
trim: true
},
playerBet: {
type: Number,
trim: true
}
}],
inProgress: {
type: Boolean,
trim: true
},
});
So clearly i can't just give it the gamers just like that, so i need to get the array given in the POST body and insert every element as name field so i can add it in the collection.
expected output
{
"id": "fffff-ggg-jjjjj",
"gamers": {
"5257b4d6-5c87-4871-93c3-b2b9ce04d706": {
"id": "5257b4d6-5c87-4871-93c3-b2b9ce04d706",
"name": "Raul Andres"
},
"8dda6205-f54c-4643-a017-71b6f0353319": {
"id": "8dda6205-f54c-4643-a017-71b6f0353319",
"name": "Juan"
},
"e5834d8e-5195-41fc-993e-c731dbce4fab": {
"id": "e5834d8e-5195-41fc-993e-c731dbce4fab",
"name": "Pedro"
}
},
"inProgress": false,
"winner": {
"id": "e5834d8e-5195-41fc-993e-c731dbce4fab",
"name": "Pedro"
}
}
router.post('/createGame', async (request, response, next) => {
try {
const { _id, gamers } = request.body;
const data = new gameModel({
_id,
players:{
name: gamers
},
inProgress: true,
});
await data.save();
response.json({
message: 'Game created successfully',
data
});
} catch (error) {
response.status(500).json({
message: error.message,
stack: error.stack
});
}
});
This is the way i was trying to do it but, name expects a String instead of an array
Thank any who can help me

You can create a gamers schema and add the id to the gamerSchema under the gamers key and store the gamers _id to the gamerSchema.gamers array

Related

Nodejs express filter data by query

I need to run the query by find like I pass id and data only with that Id will display but the issue is it's showing all data means it's not filtering.
I am finding data like this
router.get('/getannouncementsbyrestaurant/:id', async (req, res) => {
let getannouncementsbyrestaurant = await Announcements.find({ restaurants: req.params.id }).populate(['announcementRestaurants']);
if (!getannouncementsbyrestaurant) {
return res.status(400).json({ success: false, message: "something went wrong" })
}
res.status(200).json({ success: true, data: getannouncementsbyrestaurant })
})
and here is the model
const mongoose = require('mongoose');
const announcementsschema = new mongoose.Schema({
announcementName: {
type: String,
required: true
},
announcementDescription: {
type: String,
required: true
},
announcementCountry: {
type: String,
required: false
},
announcementCity: {
type: String,
required: false
},
announcementStreet: {
type: String,
default: ''
},
announcementRestaurants: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'restaurants'
},
announcementCreatedOn: {
type: Date,
default: Date.now
}
})
announcementsschema.virtual('id').get(function () {
return this._id.toHexString();
});
announcementsschema.set('toJSON', {
virtuals: true,
});
exports.Announcements = mongoose.model('Announcements', announcementsschema);
exports.announcementsschema = announcementsschema;
Don't know why its showing all data
here is example json
"data": [
{
"_id": "631a4c9c2c4fca7afc0f23f5",
"announcementName": "Mega Sale 10% off",
"announcementRestaurants": {
"_id": "631a4af62c4fca7afc0f238f",
"restaurantName": "Mega Restaurant",
},
"id": "631a4c9c2c4fca7afc0f23f5"
},
{
"_id": "631a51b72c4fca7afc0f2449",
"announcementName": "Sale upto 90%",
"announcementRestaurants": {
"_id": "631a51752c4fca7afc0f2434",
"restaurantName": "McDonalds",
},
"announcementCreatedOn": "2022-09-08T20:33:59.870Z",
"__v": 0,
"id": "631a51b72c4fca7afc0f2449"
}
]
I am passing announcementRestaurants._id in param and need to filter with that.
Your schema doesn't have the field restaurants. The corresponding field is announcementRestaurants. So the query should be:
let getannouncementsbyrestaurant =
await Announcements.find({ announcementRestaurants: req.params.id }).populate(['announcementRestaurants']);
Or
let getannouncementsbyrestaurant =
await Announcements.find({ announcementRestaurants: mongoose.Types.ObjectId(req.params.id) }).populate(['announcementRestaurants']);

updating subdocument in a modern way

hi there i came up with this solution after looking at an old post here in stackoverflow . The solituion is working fine , my only question is "there isn't a better way of doing this?".
With the last version of mongoose there isn't a way of updating a subdocument in an array simply using findOneAndUpdate ?
here is the code
exports.updateDeliveryCheck = async (req, res) => {
const values = new ParamsFormatter(req).query;
const pageId = await TemperaturesPage.findOne({ date: values.date });
TemperaturesPage.findById(pageId._id, (err, result) => {
if (!err) {
if (!result) {
res.status(404).send('Diary page not found');
} else {
result.delivery.id(values.Id).temp = +values.temp;
result.save((saveerr, saveresult) => {
if (!saveerr) {
res.status(200).send(saveresult);
} else {
res.status(400).send(saveerr.message);
}
});
}
} else {
res.status(400).send(err.message);
}
});
};
here are the schemas
const DeliveryCheckSchema = new mongoose.Schema({
product: {
type: String,
required: [true, 'Name product missing'],
},
supplier: {
type: String,
required: [true, 'Supplier name missing'],
},
temp: {
type: Number,
required: [true, 'Delivery temperature missing'],
},
date: {
type: Date,
},
actionTaken: {
type: String,
},
signature: {
type: String,
required: [true, 'Signature is missing , you are probably not logged in '],
},
note: {
type: String,
},
});
const TemperaturesPageSchema = new mongoose.Schema({
date: {
type: Date,
required: [true, 'Date for new diary page missing'],
},
delivery: [DeliveryCheckSchema],
});
as requested I add a sample data
{
"date": {
"$date": "2021-12-08T00:00:00.000Z"
},
"delivery": [{
"product": "mozzarella",
"supplier": "prestige",
"temp": 8,
"date": {
"$date": "2021-12-08T00:00:00.000Z"
},
"signature": "cristian",
"_id": {
"$oid": "61bb45a94873a3a5d7ae365e"
}
}]
}

How to get model data from nested object

little bit stuck with mongoose. I want to get all users projects where he's added. Tried few options, but in all of them I receive an empty array. So the main question is it possible somehow to find all project by filtering/finding the Project model?
This is how looks my default response to understand what I'm looking for:
{
"_id": "61a8bc4e8e24f10ac7a7288d",
"name": "Random project",
"description": "Random project desc",
"maxWorkingEmployees": 5,
"status": "Paused",
"createdBy": {
"_id": "61a66578f2dabf7555bcf4ab",
"email": "Henrikas#furniture1.eu",
"role": "Owner"
},
"currentlyWorkingEmployees": [
{
"username": "Ema",
"role": "Employee",
"_id": "61a8e0423140ecce769dc971"
}
],
"createdAt": "2021-12-02T12:30:06.461Z",
"updatedAt": "2021-12-02T15:11:51.361Z",
"__v": 0
}
Project model:
const mongoose = require('mongoose');
const SingleUserSchema = new mongoose.Schema({
username: {
type: String,
required: true,
},
role: {
type: String,
required: true,
},
});
const ProjectSchema = new mongoose.Schema(
{
name: {
type: String,
required: [true, 'Provide project name'],
minlength: 5,
},
description: {
type: String,
required: [true, 'Provide description about the project'],
},
maxWorkingEmployees: {
type: Number,
required: [
true,
'Provide maximum number of employees working on this project',
],
},
currentlyWorkingEmployees: [SingleUserSchema],
status: {
type: String,
enum: ['Pending', 'In progress', 'Paused', 'Delayed', 'Completed'],
default: 'Pending',
},
createdBy: {
type: mongoose.Schema.ObjectId,
ref: 'User',
required: true,
},
},
{ timestamps: true }
);
module.exports = mongoose.model('Project', ProjectSchema);
Here's my controller and my first try:
const getMyProjects = async (req, res) => {
const userId = req.user.userId;
const projects = await Project.find({
currentlyWorkingEmployees: { _id: userId },
});
res.json({projects});
};
Second shot after reading some articles
const getMyProjects = async (req, res) => {
const userId = req.user.userId;
const projects = await Project.aggregate([
{
$match: {
currentlyWorkingEmployees: { _id: userId },
},
},
]);
};
As I said in the comment you can do it accessing to the internal object of the schema with an string accessing to it child object.
Project.find({'currentlyWorkingEmployees._id': userId})

Want to use mongoose updateOne but it is not updating

I want to update the type: reported to type: pending under the reportStatus, but when I try it on postman I keep on getting
n:1 ,n:modified:1 and ok:1
report: [
{
category: {
type: mongoose.Schema.Types.ObjectId,
ref: "CrimeCategory",
required: true,
},
location: {
type: mongoose.Schema.Types.ObjectId,
ref: "Location",
required: true,
},
reportText: {
type: String,
required: true,
},
reportStatus: {
type: mongoose.Schema.Types.Mixed,
default: function () {
return [
{ type: "reported", date: new Date(), isCompleted: true },
{ type: "pending", isCompleted: false },
{ type: "investigating", isCompleted: false },
{ type: "solved", isCompleted: false },
];
},
},
},
],
This is the controller where I am trying to update the types that is in the model, what am I doing wrong?
const crimeReport = require("../../model/crimereport");
exports.updateReport = (req, res) => {
crimeReport
.updateOne(
{ _id: req.body.reportId, "report.reportStatus": req.body.type },
{
$set: {
"report.reportStatus.$": [
{
type: req.body.type,
date: new Date(),
isCompleted: true,
},
],
},
}
)
.exec((error, report) => {
if (error) return res.status(400).json({ error });
if (report) {
res.status(200).json({ report });
}
});
};
The postman post request:
{
"reportId": "607b2b25876fa73ec4437440",
"type":"pending"
}
This is the post result from postman:
{
"report": {
"n": 0,
"nModified": 0,
"ok": 1
}
}
It seems like, you are sending reportId in the body of post request as a string while the Mongodb document's id is of type ObjectId. You need to typecast the reportId into ObjectId, before querying to Mongodb. Since you are using Mongoose, this is the way it should be done:
mongoose.Types.ObjectId(req.body.reportId)

Unable to push object into array in Mongodb collection but Id is inserted

I am using comment array in my schema as fallows. I want to push comments data into that comment array using nodejs api
var Schema = mongoose.Schema;
var myfeeds = new Schema({
title: {
type: String,
required: true
},
feed: {
type: String,
required: true
},
createdBy: {
type: String,
required: true,
unique: true
},
createdDate: {
type: Date,
required: true,
default: Date.now()
},
comment: [
{
commentBy: {
type: String
},
commentText: {
type: String
},
createdDate: {
type: Date
}
}
],
likes: [
{
likesCount: {
type: Number,
required: false
},
likeBy: {
type: String,
required: false
}
}
]
});
I want to push object to this comment array. so, for that I did in this way please tell me if anything wrong in this
let _id = req.body.id;
let commentBy = req.body.commentedBy;
let commentedText = req.body.commentedText;
let commentedDate = req.body.commentedDate;
let data = {
commentBy: commentBy,
commentText: commentedText,
createdDate: commentedDate
};
MyFeeds.findByIdAndUpdate(
{ _id: _id },
{
$push: {
comment: data
}
}
)
.then((result) => {
res.status(200).json({
status: result
});
})
.catch((err) => {
res.status(500).json({
status: 'invalid',
err: err
});
});
but only id are inserted into that comment array but not the required content
"comment": [
{
"_id": "5badfd092b73fa14f4f0aa7c"
},
{
"_id": "5badfd102b73fa14f4f0aa7d"
},
{
"_id": "5badfd142b73fa14f4f0aa7e"
},
{
"_id": "5badfd31500fb11bb06b4c8a"
},
{
"_id": "5badfd35500fb11bb06b4c8b"
},
{
"_id": "5badff3d439a151190d62961"
}
],

Resources