Фильтровать массив объектов из другого массива объектов.Оба массива были извлечены из mongodb - PullRequest
0 голосов
/ 11 февраля 2019

Мне нужно отфильтровать массив объектов по другому массиву объектов.Вот мой сценарий:

У меня есть конечная точка драйвера, где я принимаю параметры tripId, assignTime и 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);
});

Моя проблема заключается в том, что сравнения между идентификатором конфликтующих драйверов и идентификатором всех драйверов не возвращаются точно.Если я

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

и моя поездкаСхема:

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

Я бы просто сдал и использовал сравнение по электронной почте, но мне нужно будет сделать очень похожий фильтр с использованием транспортных средств.

Я принимаюправильный подход здесь?Может быть, есть способ справиться с этим в запросе Монго?

1 Ответ

0 голосов
/ 11 февраля 2019

Я смог позаботиться об этом благодаря предложению Рохита Далала.

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);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...