从另一个对象数组中筛选对象数组.两个阵列都是从mongodb中提取的



我需要通过另一个对象数组过滤一个对象数组。这是我的方案:

有一个驱动程序端点,我正在获取tripId,departTime和returnTime的参数。从那里我拉出我所有驱动程序的数组。然后,我使用聚合来拉入冲突的驱动程序。这是我需要过滤的两个数组。

router.get("/:id/:departTime/:returnTime", [auth, admin], async (req, res) => {
  const trip = await Trip.findById(req.params.id);
  if (!trip) return res.status(404).send("Trip with given ID not found");
  //console.log(trip);
  const allDrivers = await User.find({ isDriver: true });
  const conflictedDrivers = await Trip.aggregate([
    {
      $unwind: "$drivers"
    },
    {
      $match: {
        _id: { $ne: trip._id },
        $or: [
          {
            departTime: {
              $gte: new Date(req.params.departTime),
              $lte: new Date(req.params.returnTime)
            }
          },
          {
            returnTime: {
              $gte: new Date(req.params.departTime),
              $lte: new Date(req.params.returnTime)
            }
          }
        ]
      }
    },
    {
      $project: {
        _id: "$drivers._id",
        name: "$drivers.name",
        email: "$drivers.email"
      }
    }
  ]);
  console.log("conflicted drivers: ", conflictedDrivers);
  if (conflictedDrivers.length === 0) return res.send(allDrivers);
  const availableDrivers = allDrivers.filter(driver => {
    return !conflictedDrivers.find(cd => {
      return driver._id === cd._id;
    });
  });
  console.log("available drivers: ", availableDrivers);
  res.send(availableDrivers);
});

我的问题是冲突的驱动程序 ID 和所有驱动程序 ID 之间的比较没有准确返回。如果我

return cd.email === driver.email

那么我返回的过滤数组是正确的。

这是我的用户模式:

const userSchema = new Schema({
  name: {
    type: String,
    min: 3,
    max: 50,
    required: true
  },
  email: {
    type: String,
    required: true,
    min: 5,
    max: 255,
    unique: true
  },
  password: {
    type: String,
    required: true
  },
  isAdmin: {
    type: Boolean,
    default: false
  },
  isSupervisor: {
    type: Boolean,
    default: false
  },
  isDriver: {
    type: Boolean,
    default: false
  },
  google: {
    id: String,
    token: String,
    email: String,
    name: String
  }
});

和我的旅行模式:

const tripSchema = new mongoose.Schema({
  title: {
    type: String,
    required: true
  },
  destination: String,
  physicalAddress: String,
  departTime: Date,
  returnTime: Date,
  departureLocation: String,
  organization: String,
  distance: Number,
  cost: Number,
  occupants: Number,
  tripOwner: {
    type: new mongoose.Schema({
      name: {
        type: String,
        minlength: 5,
        maxlength: 50
      },
      email: {
        type: String,
        minlength: 5,
        maxlength: 100
      }
    })
  },
  phoneNumber: String,
  vehicleTypeReq: {
    type: new mongoose.Schema({
      name: {
        type: String
      }
    })
  },
  numberOfPrimaryVehicles: Number,
  supportVehicles: Number,
  estimateNeeded: Boolean,
  numberOfDrivers: Number,
  totalVehicles: Number,
  comments: String,
  isDenied: Boolean,
  isArranged: {
    type: Boolean,
    default: false
  },
  supervisor: {
    type: new mongoose.Schema({
      name: {
        type: String,
        minlength: 5,
        maxlength: 50
      },
      email: {
        type: String,
        minlength: 5,
        maxlength: 100
      }
    })
  },
  isApproved: {
    type: Boolean,
    default: false
  },
  drivers: [userSchema],
  vehicles: [vehicleSchema]
});

我只会屈服并使用电子邮件进行比较,但接下来我需要使用车辆进行非常相似的过滤器。

我在这里采取了正确的方法吗?也许有一种方法可以在 mongo 查询中处理这个问题?

亏了Rohit Dalal的建议,我才能处理好它。

router.get("/:id/:departTime/:returnTime", [auth, admin], async (req, res) => {
  const trip = await Trip.findById(req.params.id);
  if (!trip) return res.status(404).send("Trip with given ID not found");
  const conflictedDrivers = await Trip.aggregate([
    {
      $unwind: "$drivers"
    },
    {
      $match: {
        _id: { $ne: trip._id },
        $or: [
          {
            departTime: {
              $gte: new Date(req.params.departTime),
              $lte: new Date(req.params.returnTime)
            }
          },
          {
            returnTime: {
              $gte: new Date(req.params.departTime),
              $lte: new Date(req.params.returnTime)
            }
          }
        ]
      }
    },
    {
      $project: {
        _id: "$drivers._id",
        name: "$drivers.name",
        email: "$drivers.email"
      }
    }
  ]);
  const conflictedDriversIdArray = conflictedDrivers.map(driver => {
    return driver._id;
  });
  const availableDrivers = await User.find({
    $and: [{ _id: { $nin: conflictedDriversIdArray } }, { isDriver: true }]
  });
  
  res.send(availableDrivers);
});