Home > Software design >  NodeJs, Mongoose find and populate works but aggregate, match and lookup doesn't
NodeJs, Mongoose find and populate works but aggregate, match and lookup doesn't

Time:08-24

I am having trouble with my aggregation.. I need to return the list of the items which have the same owner's id. Owner's ID I pass as a query param.. I have tried already $match without the $in,

I tried transforming my id to mongoose.Types.ObjectId (with this I event get an error). But yet I accomlpished only empty object as return..

exports.getContainersByOwner = async (req: Request, res: Response) => {
  const { id }: any = req.query;

  try {
    const containers = await Container.aggregate([
      {
        $lookup: {
          from: "containerstypes",
          localField: "containerTypeID",
          foreignField: "_id",
          as: "containerTypes",
        },
      },
      {
        $lookup: {
          from: "owners",
          localField: "ownerId",
          foreignField: "_id",
          as: "owner",
        },
      },
      { $unwind: "$containerTypes" },
      { $unwind: "$owner" },
      { $match: { "owner._id": { $in: [id] } } },
    ]);
    res.status(200).json(containers);
  } catch (err) {
    res.status(404).json({ success: false, msg: "Container not found" });
  }
};

If I remove line $match from my code api returns all the items which is OK, but I need to achieve that the returned items have the same id... I need to match the colored id (owner._id) enter image description here

The Container's model is:

const ContainerSchema = new mongoose.Schema({
  ownerId: { type: Schema.Types.ObjectId, ref: "Owners", required: true },
  manufacturingNo: { type: String, required: true },
  IdentificationNo: { type: String, required: true },
  manufacturingDate: { type: Date, required: true },
  nextInspectionDate: { type: Date, required: true },
  certificateNo: { type: String, required: false },
  containerTypeID: {
    type: Schema.Types.ObjectId,
    ref: "ContainersType",
    required: true,
  },
});

if I use this approach it works, but object structure is not right, so in frontend there is much more changes to do.. This is not possible at the moment

  try {
    const containers = await Container.find({
      ownerId: id,
    })
      .populate("containerTypeID")
      .populate("ownerId");
    res.status(200).json(containers);
  } catch (err) {
    res.status(404).json({ success: false, msg: "Container not found" });
  }

CodePudding user response:

Your $match is logically wrong:

 { $match: { "owner._id": { $in: [id] } } }

Since id, itself is a list of Ids, your $in becomes list of lists ([[]]). Try simply this:

 { $match: { "owner._id": { $in: id } } }
  • Related