如何映射 Realm 自定义解析器函数 find() 响应中的结果?

How to map over results in Realm custom resolver function find() response?

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

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]}
  })
};

我如何修复此功能以获取所有客户端并遍历它们以向每个客户端添加数据? 我明白改变这个: 让客户 = 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 错误: "message": "待定承诺返回,永远不会 resolve/reject",

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

exports = async (input) => {

    ...

    let values = await Promise.all([jobsForClient, openJobs]);
    return {...c, "jobs": values[0], "openJobs": values[1]};
}

设法通过使用 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]},
                }
              }
            },
          }
      }
  ]);
};