从另一个对象数组中过滤对象数组。两个数组都已从mongodb中拉出

时间:2019-02-11 13:04:39

标签: javascript node.js mongodb express

我需要用另一个对象数组过滤一个对象数组。这是我的情况:

我有一个驱动程序端点,我在其中获取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

然后我返回的过滤数组是正确的。

这是我的userSchema:

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

和我的tripSchema:

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查询中处理此问题?

1 个答案:

答案 0 :(得分:0)

感谢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);
});