Mongoose ignoring field while trying to save - javascript

I am trying to insert a new entry in my collection, the problem is that it ignores both doctorId and patientId while I'am sure they are not undefined. I tried to change the fields types in the definition to strings just to test whether they would be inserted and it still no use.
schema:
const RdvSchema = new mongoose.Schema({
patientId: {
type: mongoose.Schema.Types.ObjectId,
ref: "patients"
},
doctorId: {
type: mongoose.Schema.Types.ObjectId,
ref: "doctors"
},
createdAt: {
type: Date,
default: () => Date.now()
},
updatedAt: {
type: Date,
default: () => Date.now()
},
urgent: {
type: Number,
default: () => false
},
date: Date,
period: String,
description: String
})
the function saving the document:
const createRdv = async (req, res) => {
try {
console.log("patient id: ", req.body.patientId)
let rdv = new Rdv({
"patientId": req.body.patientId,
"doctorId": req.body.doctorId,
"description": req.body.description,
"urgent": req.body.urgent,
"date": req.body.date,
"period": req.body.period
})
await rdv.save(async (err, rdv) => {
if (err) {
console.log(err)
return res.status(500).send(false)
}
try {
await DoctorRepository.addRdv(req.body.doctorId, rdv._id)
await PatientRepository.addRdv(req.body.patientId, rdv._id)
} catch (message) {
console.log(message)
res.status(500).send(false)
}
})
res.status(200).send(true)
} catch (ex) {
res.status(500).send(false)
}
}
The inserted document:
{
"_id": {
"$oid": "6269603d5f0e45e53a470f50"
},
"urgent": 3,
"date": {
"$date": {
"$numberLong": "1653433200000"
}
},
"period": "matin",
"description": "this is a description",
"createdAt": {
"$date": {
"$numberLong": "1651073085661"
}
},
"updatedAt": {
"$date": {
"$numberLong": "1651073085661"
}
},
"__v": 0
}
update: for some reason An old document keeps getting inserted the document has nothing to do with what I was trying to insert. The document is one I had inserted previously through a test using Mocha

Related

How to insert value in a nested mongodb document?

I have this document:
{
"_id": {
"$oid": "63cf19337c2df5fe442a2b69"
},
"createdAt": {
"$date": {
"$numberLong": "1674516787623"
}
},
"updatedAt": {
"$date": {
"$numberLong": "1675035206032"
}
},
"clientIp": "89.132.225.21",
"products": {
"6cc5a480-91f0-4aa8-975c-013d6bd155a3": {
"currency": "EUR",
"title": "VVV",
"price": "12",
"barionId": "aa#aa.hu",
"ratingTimeLength": 12
}
}
}
I would insert like this:
const userId = req.query.userId
const productId = req.query.productId
const token = authorization.slice(7)
const userJWT = jwt.verify(token, process.env.JWT_SECRET) as JwtPayload
const ObjectId = require('mongodb').ObjectId
const id = new ObjectId().toHexString()
await collection.updateOne(
{ _id: ObjectId(userId), [`products.${productId}`]: { $exists: true } },
{
$set: {
[`products.$.payments.${id}`]: {
createdAt: new Date(),
createdBy: userJWT.userId,
},
},
},
{ upsert: true }
)
But it raise:
2023-01-29T23:43:33.653Z 1a42849c-d5aa-4127-8fdc-9169c1c6c405 ERROR MongoServerError: The positional operator did not find the match needed from the query.
When I query record in Compass, it returns the document:
{
"_id": ObjectId("63cf19337c2df5fe442a2b69"),
"products.6cc5a480-91f0-4aa8-975c-013d6bd155a3": {
"$exists": true
}
}
What is wrong?
You should access the products property directly with:
await collection.updateOne(
{ _id: ObjectId(userId), [`products.${productId}`]: { $exists: true } },
{
$set: {
[`products.payments.${id}`]: {
createdAt: new Date(),
createdBy: userJWT.userId,
},
},
},
{ upsert: true }
);

Fetching Date Data from DB returns undefined or null

I am willing to pass the dates data from my MongoDB to the antD Date Picker as disabled dates but after fetching the data of date, I get either undefined or null.
What is the approach here?
Below can be seen that my DB has date as a string converted to ISOString, but on fetching it via MongoDB, I get either undefined or null.
My main logic was to pull this date info as response.data.data in frontend after page-loading and passing this data to a useState of setUnavailable date and then assigning this setState to the disableddate function to get a boolean.
Here is my code:
The data in my DB is:
`{
"_id": {
"$oid": "63690afb0623f513b3f22704"
},
"userId": "63614c627330d358d7ceff2d",
"name": "SampleName",
"title": "Doctor",
"type": "Lab Consultation",
"description": "Help Me Please",
"timings": "2022-11-07T06:00:00.000Z",
"date": "2022-11-15T00:00:00.000Z",
"status": "pending",
"createdAt": {
"$date": {
"$numberLong": "1667828475559"
}
},
"updatedAt": {
"$date": {
"$numberLong": "1667828475559"
}
},
"__v": 0
}
`
Schema:
`const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const consultationSchema = new mongoose.Schema(
{
createdBy: {
type: mongoose.ObjectId,
ref: "userModel",
},
userId: {
type: String,
required: true,
},
name: {
type: String,
required: true,
},
title: {
type: String,
required: true,
},
type: {
type: String,
required: true,
},
description: {
type: String,
required: true,
},
timings: {
type: String,
required: true,
},
date: {
type: String,
required: true,
},
status: {
type: String,
required: false,
default: "pending",
},
},
{
timestamps: true,
}
);
const consultationModel = mongoose.model("consultations", consultationSchema);
module.exports = consultationModel;
`
Router Get Data:
`router.get("/get-all-dates", authMiddleware, async (req, res) => {
try {
const consultation = await Consultation.find({
date: { $gte: "2022-11-11T00:00:00.000Z" },
});
const dates = consultation.date;
res.status(200).send({
message: "All Dates Fetched Successfully",
success: true,
data: dates,
});
console.log(dates);
} catch (error) {
console.log(error);
res.status(500).send({
message: "Fetching Dates Failed",
success: false,
error,
});
}
});
`
API Call in React:
`const getDateData = async () => {
try {
dispatch(showLoading());
const response = await axios.get("/api/user/get-all-dates", {
headers: {
Authorization: "Bearer " + localStorage.getItem("token"),
},
});
dispatch(hideLoading());
if (response.data.success) {
setUnavailableDates(response.data.data);
console.log(response.data.data);
console.log(setUnavailableDates);
}
} catch (error) {
dispatch(hideLoading());
}
};
useEffect(() => {
getDateData();
}, []);
const disabledDate = (current) => {
// How to pass the dates fecthed from DB here? Direct with setUnavailableDates?
return current && current < moment().endOf("day");
};
`
The output in network is this:
`{
"message": "All Dates Fetched Successfully",
"success": true
}`
The output in console is: undefined

Mongoose, updated nested array

My question is:
How can I query in the nested arrays?
I want to change value in key "likeUp" which is nested inside object in array "usersWhoLiked". Where "usersWhoLiked" is nested in array "comments"
How Can I do that with mongoose ?
Request that I wrote beneath... do not work, but is very similar to answer given in StackOverflow post: Mongoose update update nested object inside an array
This is my request to db with updateOne:
try {
const response = await Comments.updateOne(
{
productId,
comments: { $elemMatch: { usersWhoLiked: { $elemMatch: { userId } } } },
},
{
$set: { 'comments.$[outer].usersWhoLiked.$[inner].likeUp': likes.up },
},
{
arrayFilters: [{ 'outer._id': commentId }, { 'inner._userId': userId }],
}
).exec();
return res.status(201).json({ response });
} catch (err) {
console.log(err);
return res.send(err);
}
This is the collection, that I am trying to update:
{
"_id": {
"$oid": "6307569d2308b78b378cc802"
},
"productId": "629da4b6634d5d11a859d729",
"comments": [
{
"userId": "62f29c2c324f4778dff443f6",
"userName": "User",
"date": "2022.08.25",
"confirmed": true,
"likes": {
"up": 0,
"down": 0
},
"content": {
"rating": 5,
"description": "Nowy komentarz"
},
"_id": {
"$oid": "630756b22308b78b378cc809"
},
"usersWhoLiked": [
{
"userId": "62f29c2c324f4778dff443f1",
"likeUp": true,
"_id": {
"$oid": "6307572d2308b78b378cc80e"
}
},
{
"userId": "62f29c2c324f4778dff443f2",
"likeUp": true,
"_id": {
"$oid": "6307572d2308b78b378cc80c"
}
}
]
}
],
"__v": 0
}
Mongooes schema for comment collection:
const commentSchema = new Schema({
productId: String,
comments: [
{
userId: String,
userName: String,
date: String,
confirmed: Boolean,
likes: {
up: {
type: Number,
default: 0,
},
down: {
type: Number,
default: 0,
},
},
content: {
rating: Number,
description: String,
},
usersWhoLiked: [{ userId: String, likeUp: Boolean }],
},
],
});
I guess the problem is with your arrayFilters operator, because you are trying to filter by field _userId which does not exist:
arrayFilters: [{ 'outer._id': commentId }, { 'inner._userId': userId }],
I managed to update the likeUp value using the following query:
db.collection.update({
_id: ObjectId("6307569d2308b78b378cc802")
},
{
$set: {
"comments.$[user].usersWhoLiked.$[like].likeUp": false
}
},
{
arrayFilters: [
{
"user._id": ObjectId("630756b22308b78b378cc809")
},
{
"like.userId": "62f29c2c324f4778dff443f1"
}
]
})
Try it on MongoDB playground: https://mongoplayground.net/p/XhQMNBgEdhp

MongooseJS: How to remove 1 object inside Array in Array of Objects

Hi MongooseJS experts!
I'm new in MongooseJS, This is my 2nd day of solving this problem but I can't find a working solution to this.
Thank you in advance!
My Delete method
Cart.updateOne(
{ "content.merchantId": req.body.merchantId },
{ $pull: { "content.items._id": req.body.productId } },
{ new: true },
function (error, result) {
if (error) { }
else if (result) { }
}
);
Schema
const CartSchema = new Schema({
customerId: {
type: String,
required: true,
},
content: {
merchantName: {
type: String,
required: true,
},
merchantId: {
type: String,
required: true,
},
items: [],
},
});
Sample JSON
[
{
"content": {
"merchantName": "SAMPLE_MERCHANT_NAME",
"merchantId": "SAMPLE_MERCHANT_ID",
"items": [
{
"_id": "SAMPLE_ID",
"title": "SAMPLE TITLE",
}
]
},
"_id": "618220e83966345ab5d451cd",
"__v": 0
},
]
Error message
Cannot use the part (_id) of (content.items._id) to traverse the element ({items: [{ _id: "SAMPLE_ID", title: "SAMPLE TITLE"}] })
you should use like this
db.collection.update({
"content.merchantId": "SAMPLE_MERCHANT_ID"
},
{
$pull: {
"content.items": {
"_id": "SAMPLE_ID"
}
}
},
{
new:true
},
)
https://mongoplayground.net/p/Ou26tab2mBU

Ideal way to store multiple texts in mongoose with Node JS?

I've been building a mongoose schema for texts that will be displayed across different pages, and it has end point to POST data for updating the texts.
For example, I would like to store text messages that will be displayed/updated in About Page and Contact Page
What would be the preferred way of designing the text model?
1) Model that has all messages stored in one data object
In front-end, the parent component fetches all text messages with Texts.findOne() and trickles down to pages that need it
const textsSchema = new Schema(
{
aboutMessage1: {
type: String,
required: true
},
aboutMessage2: {
type: String,
required: true
},
contactMessage1: {
type: String
},
contactMessage2: {
type: String
}
},
{ timestamps: true }
);
2) Model that contains each message--so it will have multiple objects
In fron-end, each page uses Text.findById(textId) to retrieve each message
const textSchema = new Schema(
{
// Example: name = contactMessage
name: {
type: String
},
message: {
type: String
}
},
{ timestamps: true }
);
3) Multiple models that contains texts for each page
Similar to 1) approach, texts get fetched with Texts.findOne(), but performed in each page
const aboutTextsSchema = new Schema(
{
message1: {
type: String,
required: true
},
message2: {
type: String,
required: true
},
},
{ timestamps: true }
);
const contactTextsSchema = new Schema(
{
message1: {
type: String,
},
message2: {
type: String,
},
},
{ timestamps: true }
);
The most promising option is the second one. Because first and third options are static, and if in the future, you need to add a new page or or a new message to an existing page, it will require changes in the mongoose model, and deployment for API.
But I think, instead of creating a text schema, it would better to create a page schema for your scenario.
Here I embed messages inside the page schema.
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const pageSchema = new Schema(
{
page: {
type: String
},
messages: [
new Schema({
name: {
type: String
},
message: {
type: String
}
})
]
},
{ timestamps: true }
);
module.exports = mongoose.model("Page", pageSchema);
Now we can use this post route to create a page:
router.post("/pages", async (req, res) => {
const result = await Text.create(req.body);
res.send(result);
});
We can create a page and its messages using the previous post route.
Request Body:
{
"_id": "5e4937e9e2454a2c0c162890",
"page": "About",
"messages": [
{
"_id": "5e4937e9e2454a2c0c162892",
"name": "Abou1",
"message": "About1 message..."
},
{
"_id": "5e4937e9e2454a2c0c162891",
"name": "Abou2",
"message": "About2 message..."
}
],
"createdAt": "2020-02-16T12:39:05.154Z",
"updatedAt": "2020-02-16T12:39:05.154Z",
"__v": 0
}
Response:
{
"_id": "5e4937e9e2454a2c0c162890",
"page": "About",
"messages": [
{
"_id": "5e4937e9e2454a2c0c162892",
"name": "Abou1",
"message": "About1 message..."
},
{
"_id": "5e4937e9e2454a2c0c162891",
"name": "Abou2",
"message": "About2 message..."
}
],
"createdAt": "2020-02-16T12:39:05.154Z",
"updatedAt": "2020-02-16T12:39:05.154Z",
"__v": 0
}
If later we want to add a message to a page we can use the following put route.
router.put("/pages/:id", async (req, res) => {
const result = await Page.findByIdAndUpdate(
req.params.id,
{
$push: { messages: req.body }
},
{ new: true }
);
res.send(result);
});
Request Body:
{
"name": "Abou3",
"message": "About3 message..."
}
Response:
{
"_id": "5e4937e9e2454a2c0c162890",
"page": "About",
"messages": [
{
"_id": "5e4937e9e2454a2c0c162892",
"name": "Abou1",
"message": "About1 message..."
},
{
"_id": "5e4937e9e2454a2c0c162891",
"name": "Abou2",
"message": "About2 message..."
},
{
"_id": "5e493926f905ab3300106f94",
"name": "Abou3",
"message": "About3 message..."
}
],
"createdAt": "2020-02-16T12:39:05.154Z",
"updatedAt": "2020-02-16T12:44:22.763Z",
"__v": 0
}
When client needs a page's messages, all we need to do is retrieving the page by it's id or page name:
router.get("/pages/id/:id", async (req, res) => {
const result = await Page.findById(req.params.id);
res.send(result);
});
//or
router.get("/pages/name/:name", async (req, res) => {
const result = await Page.findOne({ page: req.params.name });
res.send(result);
});

Categories

Resources