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

如何用Node.js、Mongoose、MongoDB高效获取排除司机已拒的订单数据

解决方案:MongoDB端过滤司机已拒绝的订单

不用把全量数据拉到前端处理,直接在MongoDB层面完成过滤,能大幅提升性能,下面是两种实用方案:

方案一:分步查询(简单高效)

先查询当前司机已拒绝的所有订单ID,再用这些ID排除对应订单:

// 1. 获取当前司机拒绝的订单ID列表
const declinedOrderIds = await db.driverResponse.find(
  { userId: "当前司机的userId", response: "DECLINED" },
  { orderId: 1, _id: 0 } // 只返回orderId字段,减少数据传输
).map(doc => doc.orderId).toArray();

// 2. 查询可用订单,排除已拒绝的
const availableOrders = await db.orders.find(
  { _Id: { $nin: declinedOrderIds } }
).toArray();

优化建议

给driverResponse集合创建复合索引,加速第一步查询:

db.driverResponse.createIndex({ userId: 1, response: 1, orderId: 1 })

这个索引能快速定位到指定司机的拒绝记录,避免全表扫描。

方案二:聚合管道(单查询完成)

用MongoDB的聚合管道一次性完成关联和过滤,适合需要复杂逻辑的场景:

const availableOrders = await db.orders.aggregate([
  // 关联driverResponse集合,获取当前订单的所有司机响应
  {
    $lookup: {
      from: "driverResponse",
      localField: "_Id",
      foreignField: "orderId",
      as: "driverResponses"
    }
  },
  // 过滤出当前司机未拒绝的订单
  {
    $match: {
      $or: [
        // 情况1:没有任何司机处理过的订单
        { driverResponses: { $size: 0 } },
        // 情况2:当前司机没有拒绝过该订单
        {
          "driverResponses": {
            $not: {
              $elemMatch: {
                userId: "当前司机的userId",
                response: "DECLINED"
              }
            }
          }
        }
      ]
    }
  },
  // 可选:移除关联的driverResponses字段,只保留订单核心数据
  { $project: { driverResponses: 0 } }
]).toArray();

优化建议

除了上述driverResponse的复合索引,还可以给orders的_Id字段确保有索引(默认自带),提升$lookup的关联效率。

方案对比

  • 分步查询:代码简洁,调试方便,数据量不大时性能最优,还可以短时间缓存declinedOrderIds减少重复查询。
  • 聚合管道:一次查询完成,适合需要同时处理多条件过滤的场景,但数据量较大时,性能可能略逊于分步查询(因为要全量关联两个集合)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 07:15:03