Returning deep nested array

I am trying to return just the array from a deep nested object. I have a top schema year, with 12 embedded months, and each month has an array of reference id’s for envelopes. I can select the specific month using this

/**
 * Get all envelopes of a month of a year
 */
yearRouter.get("/:year/:month/all", async (req, res) => {
  try {
    const { year, month } = req.params;
    const projection = {
      months: { $elemMatch: { month: month }},
    };
    const data = await Year.findOne({ year: year }, projection);
    res.json(data);
  } catch (e) {
    res.status(500).json({ message: e.message });
  }
});

and that gets me

{
    "_id": "635997a3a7099a37783cae90",
    "months": [
        {
            "month": "January",
            "total": 15000,
            "envelopes": [
                "635cae5428135652527ce99d",
                "635d1cab58ec2d6f8995f82e"
            ],
            "_id": "635997a3a7099a37783cae84",
            "remaining": -2000,
            "spent": 2000
        }
    ]
}

however I can’t seem to just get the envelope array from it. I tried originally using projection but that returned me the envelopes from every month so I am currently stuck on what to do

Hi @Evan_Goldberg and welcome to the MongoDB community forum!!

If I understand the problem correctly, you need to display only the envelopes field for the months array. To achieve the following query could be used:

test> db.new.aggregate( [ { $unwind: "$months"}, { $match: { "months.month": "March",  "year":2011}}, { $project: {"months.envelopes": 1}}])
[
  {
    _id: ObjectId("635f5cc3b11ae4deae2f0884"),
    months: {
      envelopes: [ '785cae5428135652527ce99d', '785d1cab58ec2d6f8995f82e' ]
    }
  }
]

However, please note that the above query is based on the example posted above.

If the above query does not fulfil what you are looking for, could you share

  1. A sample document for which the query is to be applied.
  2. Expected response from the query.
  3. MongoDB version you are using.

Also, please note that the official MongoDB documentation for version 6.0 states:

The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria.

Thus the query using $elemMatch returns the document that satisfies that condition as a whole. It does not return partial document. If you want to only return the matching portion, you’ll need other operations such as $project, or $unwind as in the example above.

Let us know if you have any further queries.

Best Regards
Aasawari