Home > front end >  Mongoose - How to find a Document inside an array of Documents
Mongoose - How to find a Document inside an array of Documents

Time:10-02

I have a document that has an array of documents, I want to be able to find an specific document inside this array without knowing the _id of the main document:

const organizationSchema = new Schema({
  name: { type: String, required: true, unique: true },
  members: {
   type: [{ type: Schema.Types.ObjectId, ref: "Member" }],
   default: [],
  }
 });

Members looks like this:

const memberSchema = new Schema({
 user: {
   type: Schema.Types.ObjectId,
   ref: "User",
  required: true,
 },
 status: { type: String, enum: Status, required: true },
});

Like I said before, I would like to find an Organization using the ID of an User inside the Members document, I tried to do an aggregate, but I'm doing something wrong as it just returns an empty array:

const existingOrganization = await Organization.aggregate([
  {
    $match: { "members.user._id": objectId },
  },
  {
    $unwind: "$members",
  },
]);

Is it possible to do the search in the first place?

Edit:

Here's how the document should look when retrieved from the database:

[
{
    "_id": "63376128758f036eafa9277f",
    "name": "test",
    "email": "[email protected]",
    "members": [
        {
            "_id": "63376128758f036eafa9277e",
            "user": {
                "_id": "63067438faa89240f4371f6e",
                "email": "[email protected]",
            },
            "status": "Accepted",
            "__v": 0
        }
    ],
    "__v": 0
}
]

CodePudding user response:

This could be achieved by using aggregate pipelines for Member collection.

  1. Filter members in $match stage
  2. $lookup for organizations which includes filtered members
  3. $group all the organizations
  4. $replaceRoot with organization to return a list of organizations

The solution could be:

  const existingOrganization = await Member.aggregate([
    {
      $match: {
        user: objectId
      }
    },
    {
      $lookup: {
        from: "organizations",
        localField: "_id",
        foreignField: "members",
        as: "organizations"
      }
    },
    {
      $unwind: {
        path: "$organizations"
      }
    },
    { $group: { _id: "$organizations._id", data: { $first: "$$ROOT" } } },
    { $replaceRoot: { newRoot: "$data.organizations" } }
  ]);
  • Related