无法从 graphql 突变更新 mongodb 集合
Posted
技术标签:
【中文标题】无法从 graphql 突变更新 mongodb 集合【英文标题】:unable to update a mongodb collection from the graphql mutation 【发布时间】:2020-08-21 17:39:20 【问题描述】:我无法解决以下问题。我喜欢使用 NodeJS、Apollo 和 Mongoose 开发 GraphQL 服务器。
以下是数据库中的一些示例数据:
处方设置
"_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
]
我想做的是,从 ParsedPdf 上的每个数组中获取“name”和“value”,检查其中“value”位于 PrescriptionSetup 的“valueFrom”和“valueTo”之间,并更新“detail”与“description”和“recommendation”。
这就是我所做的。我创建了一个突变:
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方法
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);
;
ParsedPdf 集合中有很多数组,其中包含很多项目。我认为由于大量的数据库查询,我无法使其工作。 解决此问题的最佳方法是什么。
感谢您的帮助
【问题讨论】:
您确定value
中的ParsedPdf
是String
吗?而valueFrom
、valueTo
是Number
s?什么不起作用是有错误还是没有按预期更新?
我观察到的您的问题主要与异步操作有关。你忘了把await
放在它应该出现的地方,你把它们放在不应该出现的地方
@TheeSritabtim 你能告诉我await
的正确位置吗? find
查询正在运行。
【参考方案1】:
我会建议一种代码更改最少的方法。
const pp = PrescriptionSetup.find
这里pp
是Promise
,所以newRep
将是Promise
s 的数组
用[...await Promise.all(newRep)]
代替[...newRep]
await Object.keys(pdf).forEach((key) => ...)
这里.forEach
不返回任何内容,实际上你不必返回await
,但我们只是在 (1.) 中添加了一个异步逻辑,所以我们必须处理它
如果您使用 bluebird
,请更改为 await Promise.map(Object.keys(pdf), async (key) => ...)
,否则请使用与 Promise.map 等效的内容
【讨论】:
谢谢。这解决了问题。之前没听说过bluebird
,试一试。谢谢你的建议?。以上是关于无法从 graphql 突变更新 mongodb 集合的主要内容,如果未能解决你的问题,请参考以下文章
如何进行更新突变 - GraphQL(加上 mongoDB)
Express-graphql“在运行突变和查询时无法使用 mongodb 读取未定义的属性‘集合’”
带有 Stripe 和 MongoDB 集成的 GraphQL 突变过早返回 null [重复]
如何在 graphql 和 mongodb 的一个突变中保存多行?
如何修复 TypeError:在使用 bcryptjs 对 GraphQL 突变进行哈希密码期间无法读取未定义的属性“哈希”?