Reputation: 2027
I am having trouble solving the following issue. I satrted to develop GraphQL server using NodeJS, Apollo and Mongoose.
Below are some of the sample data from the database:
PrescriptionSetup
{
"_id": "5ea99ae6fc48d036e083ec20",
"name": "Calcium",
"valueTo": -51,
"valueFrom": -75,
"treatmentDescription": "Deficiency",
"recommendation": "<p><strong>Calcium Deficiency</strong></p>\n<p><strong>S & S include: </strong></p>\n<p>Anxiety, Muscle cramps, and spasms, Bruising, Nervousness, Insomnia, Osteoporosis, Tooth decay</p>\n<p><strong>Calcium sources:</strong></p>\n<p>Milk, cheese and other dairy foods. Broccoli, cabbage and okra, Soya beans, Nuts, Flour, Fish</p>",
"isNormal": false
},
{
"_id": "5ea99ae6fc48d036e083ec21",
"name": "Calcium",
"valueTo": 100,
"valueFrom": 76,
"treatmentDescription": "High Bio-unavailable",
"recommendation": "<p><strong>Calcium Excess</strong></p>\n<p><strong>S & S include:</strong></p>\n<p>Arthritis, Gall stones, Constipation, Kidney stones, Depression, Mental, Fatigue.</p>\n<p><strong>Calcium sources:</strong></p>\n<p>Milk, cheese and other dairy foods.Broccoli, cabbage and okra, Soya beans, Nuts, Flour, Fish</p>",
"isNormal": false
},
{
"_id": "5ea99ae6fc48d036e083ec89",
"name": "Calcium",
"valueTo": -26,
"valueFrom": -50,
"treatmentDescription": "Border line deficiency",
"recommendation": "<p><strong>Calcium Borderline Deficiency</strong></p>\n<p><strong>S & S include: </strong></p>\n<p>Fatigue.Weak and brittle fingernails.Poor appetite. Muscle cramps, stiffness, and spasms.</p>\n<p><strong>Calcium sources:</strong></p>\n<p>Milk, cheese and other dairy foods. Broccoli, cabbage and okra, Soya beans.<br /> Nuts. Flour. Fish</p>",
"isNormal": false
},
{
"_id": "5ea99ae6fc48d036e083ec8a",
"name": "Calcium",
"valueTo": -76,
"valueFrom": -100,
"treatmentDescription": "insufficiency",
"recommendation": "<p><strong>Calcium Insufficiency</strong> <br /><strong>S & S include: </strong></p>\n<p>Anxiety, Muscle cramps and spasms, Bruising, Nervousness, Insomnia, Osteoporosis, Tooth decay</p>\n<p><strong>Calcium sources:</strong></p>\n<p>Milk, cheese and other dairy foods.Broccoli, cabbage and okra, Soya beans , Nuts , Flour , Fish</p>",
"isNormal": false
},
{
"_id": "5ea99ae6fc48d036e083ec22",
"name": "Magnesium",
"valueTo": 100,
"valueFrom": 76,
"treatmentDescription": "High Bio-unavailable",
"recommendation": "<p><strong>Magnesium Excess</strong></p>\n<p><strong>S & S include:</strong></p>\n<p>Confusion, Fatigue, Depression, Low blood pressure, Diarrhea, Muscle weakness</p>\n<p><strong>Magnesium sources:</strong></p>\n<p>Spinach, figs, avocado, banana and raspberries. Nuts and seeds. Legumes. Peas, broccoli, cabbage, green beans, artichokes, Seafood</p>",
"isNormal": false
},
{
"_id": "5ea99ae6fc48d036e083ec53",
"name": "Magnesium",
"valueTo": 25,
"valueFrom": -25,
"treatmentDescription": "Normal / Ideal zone",
"recommendation": "",
"isNormal": true
},
ParsedPdf
{
_id: "5eb2da3a4c6ccc6f65d7e621",
"mineralTestReport":
[
{
"name": "Calcium",
"value": "25",
"details": null
},
{
"name": "Magnesium",
"value": "-25",
"details": null
},
{
"name": "Phosphorus",
"value": "-71",
"details": null
},
],
"ratios":
[
{
"name": "Ca/Mg",
"value": "43",
"details": null
},
{
"name": "Ca/P",
"value": "100",
"details": null
},
{
"name": "K/Na",
"value": "-75",
"details": null
},
{
"name": "Cu/Zn",
"value": "-3",
"details": null
}
]}
What I wanted to do is, take the "name" and "value" from each of the array on the ParsedPdf, check where the "value" lies in between the "valueFrom" and "valueTo" from the PrescriptionSetup and update the "detail" with "description" and "recommendation".
This is what I did. I created a Mutation:
updateParsePdf: authenticated(async (parent, args, context, info) => {
try {
const pdf = await ParsePdf.findById(args._id);
const newReport = await updatedReport(pdf._doc);
const reportUpdated = await ParsePdf.findByIdAndUpdate(args._id, {
newReport,
}).exec();
return reportUpdated._doc;
} catch (error) {
console.log("error: ", error);
throw new AuthenticationError("Opps! Something went wrong.", error);
}
}),
updateReport method
const updatedReport = async (pdf) => {
//pdf is the response from the ParsedPdf above
let updated = {};
try {
await Object.keys(pdf).forEach((key) => {
const field = pdf[key];
if (Array.isArray(field)) {
const newRep = field.map(async (f) => {
const pp = PrescriptionSetup.find({
name: f.name,
valueFrom: {
$lte: f.value,
},
valueTo: {
$gte: f.value,
},
})
.exec()
.then((p) => {
return {
...f,
details: {
description: p[0].treatmentDescription,
recommendation: p[0].recommendation,
isNormal: p[0].isNormal,
},
};
})
.catch((e) => {
console.log("Error finding setup: ", e);
});
return pp;
});
updated = { ...updated, [key]: [...newRep] };
}
});
const aa = { ...pdf, ...updated };
return aa;
} catch (error) {
console.log("Error...: ", error);
}
};
There are lots of Arrays inside the ParsedPdf collection with lots of items in it. I think because of the huge db queries, I could not make it work. What is the best approach to solve this.
Thanks for the help
Upvotes: 1
Views: 405
Reputation: 5245
I'll suggest an approach with the least code change.
const pp = PrescriptionSetup.find
here pp
is a Promise
, so newRep
will be array of Promise
s
instead of [...newRep]
use [...await Promise.all(newRep)]
await Object.keys(pdf).forEach((key) => ...)
here .forEach
doesn't return anything, actually you don't have to await
, but we just aded an async logic in (1.) so we have to handle that
change to await Promise.map(Object.keys(pdf), async (key) => ...)
if you use bluebird
, else use something equivalent with Promise.map
Upvotes: 1