无法从 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 &amp; 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&Acirc;&nbsp;foods. Broccoli, cabbage and okra, Soya beans, Nuts, Flour,&nbsp;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 &amp; 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&nbsp;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 &amp; 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&Acirc;&nbsp;foods. Broccoli, cabbage and okra, Soya beans.<br /> Nuts. Flour.&nbsp;Fish</p>",
                "isNormal": false
            ,
            
                "_id": "5ea99ae6fc48d036e083ec8a",
                "name": "Calcium",
                "valueTo": -76,
                "valueFrom": -100,
                "treatmentDescription": "insufficiency",
                "recommendation": "<p><strong>Calcium Insufficiency</strong> <br /><strong>S &amp; 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&Acirc;&nbsp;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 &amp; 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 valueToNumbers?什么不起作用是有错误还是没有按预期更新? 我观察到的您的问题主要与异步操作有关。你忘了把await放在它应该出现的地方,你把它们放在不应该出现的地方 @TheeSritabtim 你能告诉我await 的正确位置吗? find 查询正在运行。 【参考方案1】:

我会建议一种代码更改最少的方法。

    const pp = PrescriptionSetup.find 这里ppPromise,所以newRep 将是Promises 的数组

    [...await Promise.all(newRep)]代替[...newRep]

    await Object.keys(pdf).forEach((key) =&gt; ...) 这里.forEach 不返回任何内容,实际上你不必返回await,但我们只是在 (1.) 中添加了一个异步逻辑,所以我们必须处理它

    如果您使用 bluebird,请更改为 await Promise.map(Object.keys(pdf), async (key) =&gt; ...),否则请使用与 Promise.map 等效的内容

【讨论】:

谢谢。这解决了问题。之前没听说过bluebird,试一试。谢谢你的建议?。

以上是关于无法从 graphql 突变更新 mongodb 集合的主要内容,如果未能解决你的问题,请参考以下文章

如何进行更新突变 - GraphQL(加上 mongoDB)

Express-graphql“在运行突变和查询时无法使用 mongodb 读取未定义的属性‘集合’”

带有 Stripe 和 MongoDB 集成的 GraphQL 突变过早返回 null [重复]

无法使用 graphql 突变更新流星用户集合

如何在 graphql 和 mongodb 的一个突变中保存多行?

如何修复 TypeError:在使用 bcryptjs 对 GraphQL 突变进行哈希密码期间无法读取未定义的属性“哈希”?