how to save data to the array in mongoose - javascript

I am building an application where user's can save many images along with its name. I want that information to be stored in mongoose in an array. How to do this?
Here is my mealSchema,
const MealSchema = new mongoose.Schema({
userId: {
type: String,
required: true,
},
meals: [
{
mealImg: {
type: String,
},
mealName: {
type: String,
},
},
],
});
how to save data to this schema.
I want the result to be like this :
{ _id: 5fd662b596ac96247463fab8,
userId:"someid"
meals: [
{
_id:23242fff,
mealName:"meal1",
mealImg:"https://meal1.png"
},
_id:23242fff,
mealName:"meal2",
mealImg:"https://meal3.png"
},
_id:23242fff,
mealName:"meal3",
mealImg:"https://meal4.png"
},
] }

You can write smth like this:
Meal.insert({ userId: someId, meals: arrayOfMeals })
But this is not a good practice, because you can put unnecessary and incorrect information in the array. Such problems are solved by intermediate tables and links between them. I advise you to create another table, the scheme of which will be as follows:
const UsersMealsSchema = new mongoose.Schema({
userId: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
mealId: {type: mongoose.Schema.Types.ObjectId, ref: 'Meal'},
});
Then change your Meals shema:
const MealSchema = new mongoose.Schema({
id: {
type: string,
required: true,
}
mealImg: {
type: String,
required: true,
},
mealName: {
type: String,
required: true,
},
});

Related

In MongoDB, when deleting a dataset how do I also remove the associated "child" datasets?

Example: If I delete a user, I want to also remove all of that users associated comments.
const UserSchema = new Schema(
{
username: {
type: String,
unique: true,
},
email: {
type: String,
unique: true,
},
comments: [
{
type: Schema.Types.ObjectId,
ref: "Comment"
}
],
);
Right now I am removing a user with the .findOneAndDelete method.

How to use mongoose transactions with updateMany?

I am using the mongoose updateMany() method and I also want to keep it a part of transaction. The documentation shows the example of save() where I can do something like Model.save({session: mySession}) but don't really know how to use it with for example Model.updateMany()
UPDATE:
For example I have two models called SubDomain and Service and they look like this respectively:
SUB-DOMAIN
{
name: {
type: String,
required: true,
},
url: {
type: String,
required: true,
unique: true,
},
services: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Service",
},
],
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
},
}
SERVICE:
{
name: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
price: { type: Number },
tags: { type: Array },
packages: [
{
name: { type: String, required: true },
description: { type: String, required: true },
price: { type: Number, required: true },
},
],
map: { type: String },
isHidden: {
type: Boolean,
required: true,
default: false,
},
sortingOrder: { type: Number },
isForDomain: { type: Boolean, required: false, default: false },
isForSubDomain: { type: Boolean, required: false, default: false },
subDomains: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "SubDomain",
},
],
}
Now the main field here is the services field in SubDomain and subDomains field in Service.
The complicated part😅:
Whenever the user wants to create new service, I want to $push that service's _id into the array of services of all the subDomains inside that new service
And for that, I am using the updateMany() like this:
const sess = await mongoose.startSession();
sess.startTransaction();
const newService = new Service({
_id: mongoose.Types.ObjectId(),
subDomains: req.body.subDomains
...foo
})
await SubDomain.updateMany(
{ _id: { $in: req.body.subDomains } },
{ $push: { services: newService._id } }
);
The problem starts here, of course I can do:
newService.save({session: sess})
but how do I keep my SubDomain's updateMany in the same transaction (i.e sess)
I know my example is difficult to wrap your head around but I have tried to pick a simplest example rather than copying the exact same code which would have been a lot more difficult

Find item in an array of Objectid references

I have an array of objectIDs references in mongo. I want to get a specific element in that array after populating the objectIDs. the problem is i get an empty array.
Here's my schema
// Patient Schema - start
const patientSchema = new mongoose.Schema({
nom: {
type: String,
required:true
},
prénom: {
type: String,
required:true
},
naissance:{
type:Date,
},
adresse: {
type: String,
required:true
},
téléphone: {
type: String,
required:true
},
profession: {
type: String,
},
/// the field i'm trying to populate
consultations:[{
type: mongoose.Schema.Types.ObjectId,
ref:'Consultation'
}],
salle:{
type: mongoose.Schema.Types.ObjectId,
required: true,
ref:'Salle'
},
date:{
type:String,
default: Date.now
},
jointes: {
type:Array
},
questionnaire: {
type:Object
},
}, { collection : 'patients'} );
const patients = mongoose.model('Patient', patientSchema);
Consultation schema
const consultationSchema = new mongoose.Schema({
date: {
type: String,
required:true
},
motif:{
type: String,
},
observations: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Observation"
}],
paiements: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Paiement"
}],
ordonnances: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Ordonnance"
}]
});
const consultations = mongoose.model('Consultation', consultationSchema);
the exports
module.exports = {
patients: patients,
consultations: consultations,
}
The router where i'm trying to populaet consultation field and then get the item
const {patients} = require('./patient.models')
const {consultations} = require('./patient.models')
// not working , getting empty array
const patient = await patients.find({"consultations.motif" : "Checking"}).populate('consultations')
res.send(patient)
The mongo db record , to show you that the field does exist
Here's what i get when i do make the following query iwthout specifiying the field
const patient = await patients.find().populate('consultations')
res.send(patient)
This question already has been answered here: Find after populate mongoose
Here is the solution for your case which does not involve changing the database structure:
const patient = await patients.find().populate({
path: 'consultations',
match: {
motif: 'Checking'
}
})
res.send(patient)

How can I save this JSON to a mongoDB database serviced by MonogDB Compass?

I have some raw JSON that I have populated for testing purposes, but now I would like to put it into a mongoDB database using mongoDB Compass.
My mongoDB connection string is working and I have working mongoose code.
How do I go about doing this?
I would hope this would be an easy task as mongoDB stores it's data in the form of BSON already.
Here is a snippet of my code.
const json_string =
`[
{
"link": "https://www.youtube.com/watch?v=BMOjVYgYaG8",
"image": "https://i.imgur.com/Z0yVBpO.png",
"title": "Debunking the paelo diet with Christina Warinner",
// ... snip
},
{ // ... snip
The schema is already created:
// for relevant data from google profile
schema.Article = new Schema({
link: { type: String, required: true },
image: { type: String, required: true },
title: { type: String, required: true },
summary: { type: String, required: true },
tag: { type: String, required: true },
domain: { type: String, required: true },
date: { type: String, required: true },
timestamp: { type: Date, default: Date.now }
});
You can use this
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
mongoose.connect(process.env.MONGO_URI);
const articleSchema = new Schema({
link: { type: String, required: true },
image: { type: String, required: true },
title: { type: String, required: true },
summary: { type: String, required: true },
tag: { type: String, required: true },
domain: { type: String, required: true },
date: { type: String, required: true },
timestamp: { type: Date, default: Date.now }
});
const Article = mongoose.model("Article", articleSchema);
const json_string = `[
{
"link": "https://www.youtube.com/watch?v=BMOjVYgYaG8",
"image": "https://i.imgur.com/Z0yVBpO.png",
"title": "Debunking the paelo diet with Christina Warinner"
}
]`;
const jsonBody = JSON.parse(json_string);
for (let i = 0; i < jsonBody.length; i++) {
const data = jsonBody[i];
const article = new Article({
link: data.link,
image: data.image,
title: data.title
//.... rest
});
article.save();
}
Convert JSON string to an array
Loop through each object in the array
Create a new Article instance based on values from the object
Call the save method on the Article object

Mongoose not saving changes to a document

I'm sorry if this might be a duplicate question but I'm quite having a hard time understanding Mongoose. I am working on a Node.js project that implements Mongoose and MongoDB. What I want to accomplish is to modify and save some users' data through a call from a specific endpoint.
Mongoose Schema looks like this
var UserSchema = new Schema({
isAdmin: {type: Boolean, default: false},
name: String,
surname: String,
nickname: { type: String },
email: { type: String, lowercase: true, required: true, trim: true, unique: true, dropDubs: true },
password: { type: String, required: true },
salt: { type: String },
verified: { type: Boolean, default: false },
bio: {
type: { type: String, enum: [0,1] }, // 0='Appassionato', 1='Giocatore'
birthday: String,
height: Number,
number: Number,
role: { type: String, enum: [0,1,2,3] }, // 0='Playmaker', 1='Ala', 2='Guardia', 3='Centro'
team: String,
city: String,
aboutMe: String,
},
newsletter: {type: Boolean, default: false},
lastCheckin: {type: mongoose.Schema.Types.ObjectId, ref: 'Checkin'},
follows: [{type: mongoose.Schema.Types.ObjectId, ref: 'Structure'}],
score: { type: Number, default: 0 },
profilePicture: String,
lastLogin: {type: Date},
facebook: {
id: String,
accessToken: String,
profileImage : String
}
}, {
collection: 'users',
retainKeyOrder: true,
timestamps: true,
}).plugin(mongoosePaginate);
Following is the code for when the endpoint gets interrogated
exports.updateUser = (req,res) => {
var userId = req.params.userId;
var updates = req.body;
User.findOneAndUpdate({_id: userId}, {$set: updates}, (err, saved) => {
if (!err) {
console.log("Ritorno questo: " + saved);
return res.status(202).json(saved);
} else {
return res.status(500).json(saved);
}
});
};
As far as I understood, the method findOneAndUpdate exposed by Mongoose should find the document I'm looking for and then modify it and save it. This doesn't happen though.
Through PostMan I'm sending this JSON
{"bio.aboutMe":"Hello this is just a brief description about me"}
But PostMan is responding with the non-modified object. What am I missing here?
What you need to do is to add {new:true}, it give you back the updated document.
In the documentation :
If we do need the document returned in our application there is
another, often better, option:
> Tank.findByIdAndUpdate(id, { $set: { size: 'large' }}, { new: true },
> function (err, tank) { if (err) return handleError(err);
> res.send(tank); });
This is something I don't really like as there is another option if we don't want to have the document → update
So what you need to do is :
User.findOneAndUpdate({_id: userId}, {$set: updates}, {new:true}.....

Categories