You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取Mongoose Cursor流文档总数?解决批量发送剩余数据问题

解决Mongoose Cursor遍历剩余文档未发送及获取总数问题

你遇到的核心问题有两个:一是遍历结束后剩余不足50条的文档没被发送到API,二是想获取当前cursor对应的总文档数量。下面给你针对性的解决方案:

一、修复剩余文档未发送的问题

你的现有代码只在每积累50条时发送一次,但遍历结束后如果res里还有剩下的文档(比如总共有53条,最后3条就会留在数组里),就会被遗漏。我们只需要在eachAsync执行完成后,额外检查并发送剩余内容即可:

async function exportQuotes(from, to) {
  let i = 0; // 调整初始值,让计数逻辑更直观
  let res = [];
  const quotes = findQuotes(from, to);
  
  // 遍历cursor中的每一条文档
  await quotes.eachAsync(async (doc) => {
    res.push(quoteMapper(doc));
    i += 1;
    
    // 每积累50条就发送一次
    if (i === 50) {
      await sendQuotesTest(res);
      // 重置计数器和数组
      i = 0;
      res = [];
    }
  });
  
  // 遍历结束后,发送剩下的不足50条的文档
  if (res.length > 0) {
    await sendQuotesTest(res);
  }
  
  return Promise.resolve(); // 可根据需求返回统计结果或其他数据
}

二、获取Cursor对应的文档总数

Mongoose的cursor本身不会直接返回总条数,我们需要单独执行一个和findQuotes过滤条件完全一致的计数查询:

// 单独封装计数函数,确保过滤条件和findQuotes保持同步
async function getQuotesTotalCount(from, to) {
  return Draft.countDocuments({
    lastPriceRequest: { $ne: null },
    updatedAt: {
      $gte: from.toISOString(),
      $lte: to.toISOString(),
    },
  });
}

然后在exportQuotes中调用这个函数,就能拿到总条数了:

async function exportQuotes(from, to) {
  // 先获取总文档数
  const totalCount = await getQuotesTotalCount(from, to);
  console.log(`本次需要处理的文档总数:${totalCount}`);
  
  let i = 0;
  let res = [];
  const quotes = findQuotes(from, to);
  
  await quotes.eachAsync(async (doc) => {
    res.push(quoteMapper(doc));
    i += 1;
    
    if (i === 50) {
      await sendQuotesTest(res);
      i = 0;
      res = [];
    }
  });
  
  if (res.length > 0) {
    await sendQuotesTest(res);
  }
  
  // 可以返回处理统计信息
  return {
    totalCount,
    processedCount: totalCount // 这里假设所有文档都成功处理,实际可根据情况调整
  };
}

关于计数的小提示

  • countDocuments会精确统计符合过滤条件的文档数量,但对于超大数据集可能会有轻微性能开销。
  • 如果不需要精确计数,也可以用estimatedDocumentCount,但它会忽略过滤条件,只返回集合的大致文档总数,所以不适合你的场景。

额外优化建议

  • 给sendQuotesTest添加错误处理逻辑,比如捕获请求失败的异常,记录日志或进行重试,避免因为单次API调用失败导致整个流程中断。
  • 因为eachAsync默认是串行执行的,所以不用担心并发发送API请求的问题;如果需要提高效率,可以考虑设置parallel参数,但要注意API的并发限制。

内容的提问来源于stack exchange,提问作者Flo4555

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 18:38:12