Home > Mobile >  Mongodb and nodejs find and filter nested objects
Mongodb and nodejs find and filter nested objects

Time:11-03

Firstly this is my Workspaces collection

[
    {
        "WorkspaceId": "er890we8rw98ro9we8rjower",
        "WorkspaceTitle": "My First Workspace",
        "WorkspaceOwner": "user1",
        "Pages": [
            {
                "PageId": "a1sd32as7d841a23sd",
                "PageMembers": [
                    {
                        "MemberId": "user1",
                        "MemberName": "John",
                        "MemberAvatar": "https://example.com/jKLa29Wqy",
                        "MemberAccess": "can edit"
                    },
                    {
                        "MemberId": "user2",
                        "MemberName": "Margot",
                        "MemberAvatar": "https://example.com/wKKLSAqy",
                        "MemberAccess": "can edit"
                    },
                    {
                        "MemberId": "user3",
                        "MemberName": "Silvia",
                        "MemberAvatar": "https://example.com/wKKLSAqy",
                        "MemberAccess": "can edit"
                    },
                    ...
                ]
            }
        ]
    }
]

I wanr to print specific nested objects from document. I need to get a specific document inside my collection like this.

{
  "WorkspaceId": "er890we8rw98ro9we8rjower",
  "WorkspaceTitle": "My First Workspace",
  "WorkspaceOwner": "user1",
  "Pages": [
    {
      "PageId": "a1sd32as7d841a23sd",
      "PageMembers": [
        {
          "MemberId": "user1",
          "MemberName": "John",
          "MemberAvatar": "https://example.com/jKLa29Wqy",
          "MemberAccess": "can edit"
        }
      ]
    }
  ]
}

But when I run this script, my api prints all of collection. How can I achieve this?

Below is the query I am using:

db.findOne({ $or: [{ "WorkspaceOwner": member_id }, { "Pages.PageMembers.MemberId": member_id }] }, function (err, result) {
            res.status(200).json(result);
});

CodePudding user response:

You can achieve by using unwind and filter aggregation.

db.collection.aggregate([
  {
    "$unwind": "$Pages"
  },
  {
    $addFields: {
      "Pages.PageMembers": {
        $filter: {
          input: "$Pages.PageMembers",
          as: "temp",
          cond: {
            $in: [
              "$$temp.MemberId",
              [
                "user1"
              ]
            ]
          }
        }
      }
    }
  }
])

Playground

  • Related