Py学习  »  MongoDB

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

Greg Leeper • 5 年前 • 271 次点击  

我需要用另一个对象数组过滤一个对象数组。下面是我的场景:

我有一个驱动程序端点,在这里我将获取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
  }
});

我的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查询中有一种方法可以处理这个问题?

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/30806
 
271 次点击  
文章 [ 1 ]  |  最新文章 5 年前
Greg Leeper
Reply   •   1 楼
Greg Leeper    5 年前

多亏了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);
});