1

我正在尝试为我的自定义解析器创建一个函数,该函数获取集合中的所有文档并返回带有新数据的修改后的有效负载。下面是我用来获取一个客户端并修改其数据的代码:

exports = (input) => {
  const clientId = input._id;
  const openStatusId = new BSON.ObjectId("898999");
  
  const mongodb = context.services.get("mongodb-atlas");
  const clientRecords = mongodb.db("db-name").collection("clients");
  const jobRecords = mongodb.db("db-name").collection("jobs");
  
  let client = clientRecords.findOne({"_id": clientId});
  const query = { "client_id": clientId};

  let jobsForClient = jobRecords.count(query)
  .then(items => {
    console.log(`Successfully found ${items} documents.`)
    // items.forEach(console.log)
    return items
  })
  .catch(err => console.error(`Failed to find documents: ${err}`));
  
  let openJobs = jobRecords.count({"client_id": clientId,"status": openStatusId})
  .then(numOfDocs => {
    console.log(`Found ${numOfDocs} open jobs.`)
    // items.forEach(console.log)
    return numOfDocs
  })
  .catch(err => console.error(`Failed to find documents: ${err}`));
  
  return Promise.all([client, jobsForClient, openJobs]).then(values => {
    return {...values[0], "jobs": values[1], "openJobs": values[2]}
  })
};

如何修复此功能以获取所有客户端并循环它们以向每个客户端添加数据?我明白改变这个: let client = clientRecords.findOne({"_id": clientId}); 为此,让客户 = clientRecords.find();

将从客户端集合中获取所有文档。之后我将如何遍历每个客户端?

更新

我已将该函数更新为以下内容,并且在领域环境中运行它时它可以工作,但在将它作为 GraphQL 查询运行时给我一个错误。

更新代码:

exports = (input) => {
  const openStatusId = new BSON.ObjectId("999999");
  
  const mongodb = context.services.get("mongodb-atlas");
  const clientRecords = mongodb.db("db-name").collection("clients");
  const jobRecords = mongodb.db("db-name").collection("jobs");
  
  const clients = clientRecords.find();

  const formatted = clients.toArray().then(cs => {
    return cs.map((c,i) => {
      const clientId = c._id;
      const query = { "client_id": clientId};
      
      let jobsForClient = jobRecords.count(query)
      .then(items => {
        console.log(`Successfully found ${items} documents.`)
        // items.forEach(console.log)
        return items
      })
      .catch(err => console.error(`Failed to find documents: ${err}`));
      
      let openJobs = jobRecords.count({"client_id": clientId,"status": openStatusId})
      .then(numOfDocs => {
        console.log(`Found ${numOfDocs} open jobs.`)
        // items.forEach(console.log)
        return numOfDocs
      })
      .catch(err => console.error(`Failed to find documents: ${err}`));
      
      return Promise.all([jobsForClient, openJobs]).then(values => {
        return {...c, "jobs": values[0], "openJobs": values[1]}
      });
    })
  }).catch(err => console.error(`Failed: ${err}`));
  
  return Promise.all([clients, formatted]).then(values => {
        return values[1]
      }).catch(err => console.error(`Failed to find documents: ${err}`));
};

GraphQL 中的错误:“消息”:“返回的未决承诺永远不会解决/拒绝”,

4

2 回答 2

0

看起来您需要等待函数中的最后一个承诺在函数返回之前解决。我会做这样的事情:

exports = async (input) => {

    ...

    let values = await Promise.all([jobsForClient, openJobs]);
    return {...c, "jobs": values[0], "openJobs": values[1]};
}
于 2022-01-12T03:43:42.370 回答
0

通过使用 mongodb 聚合来解决。解决方案如下:

exports = async function(input) {


const openStatusId = new BSON.ObjectId("xxxxxx");
  
  const mongodb = context.services.get("mongodb-atlas");
  const clientRecords = mongodb.db("xxxxx").collection("xxxx");
  const jobRecords = mongodb.db("xxxxx").collection("xxxx");
  
  return clientRecords.aggregate([
      {
          $lookup: {
              from: "jobs",
              localField: "_id",
              foreignField: "client_id",
              as: "totalJobs"
          }
      },
      {
          $addFields: {
            jobs: { $size: "$totalJobs" },
            openJobs: {
              $size: {
                $filter: {
                  input: "$totalJobs",
                  as: "job",
                  cond: { "$eq": ["$$job.status", openStatusId]},
                }
              }
            },
          }
      }
  ]);
};
于 2022-02-01T14:40:01.573 回答