skip to Main Content

My query

  const users = usersWorkspaceModel
    .find({
      workspaceId,
      userRole: 'supervisor',
    })
    .select({
      _id: 0,
      createdAt: 0,
      assignedBy: 0,
      updatedAt: 0,
      workspaceId: 0,
    })
    .populate({
      path: 'userId',
      select: ['_id', 'name', 'email'],
      mode: 'User',
    });

This returns me the following result :-

 "users": [
        {
            "userId": {
                "_id": "634e890c9de1ec46aad0015a",
                "name": "supervisor-abdullah-new",
                "email": "[email protected]"
            },
            "userRole": "supervisor",
            "busy": false,
            "socketId": null
        },
        {
            "userId": {
                "_id": "633d498fc3935aa2ab1f9af6",
                "name": "supervisor-abdullah",
                "email": "[email protected]"
            },
            "userRole": "supervisor",
            "busy": false,
            "socketId": null
        },
    ]

The result that I want :-

"users": [
        {
            "_id": "634e890c9de1ec46aad0015a",
            "name": "supervisor-abdullah-new",
            "email": "[email protected]",
            "userRole": "supervisor",
            "busy": false,
            "socketId": null
        },
        {
            "_id": "633d498fc3935aa2ab1f9af6",
            "name": "supervisor-abdullah",
            "email": "[email protected]",
            "userRole": "supervisor",
            "busy": false,
            "socketId": null
        },
    ]

usersWorkspaceModel Collection :-

{
  "_id": {
    "$oid": "634feda89b9ebdf9a12aa7c1"
  },
  "userId": {
    "$oid": "6347bf9befe34bf785fb9a07"
  },
  "userRole": "supervisor",
  "workspaceId": {
    "$oid": "6347de1e81a714995bb497b1"
  },
  "assignedBy": {
    "$oid": "633c3409f2c19af92e788ac6"
  },
  "busy": false,
  "socketId": null,
  "createdAt": {
    "$date": {
      "$numberLong": "1666182568991"
    }
  },
  "updatedAt": {
    "$date": {
      "$numberLong": "1666187418223"
    }
  }
},{
  "_id": {
    "$oid": "634ea79850cbfd7e532d27a7"
  },
  "userId": {
    "$oid": "633d498fc3935aa2ab1f9af6"
  },
  "userRole": "supervisor",
  "workspaceId": {
    "$oid": "633fd3235788f7cd7222c19e"
  },
  "assignedBy": {
    "$oid": "633c3409f2c19af92e788ac6"
  },
  "busy": false,
  "socketId": null,
  "createdAt": {
    "$date": {
      "$numberLong": "1666099096965"
    }
  },
  "updatedAt": {
    "$date": {
      "$numberLong": "1666247564289"
    }
  }
}

Users Collection:-

{
  "_id": {
    "$oid": "63354ddcdddc0907714a8622"
  },
  "name": "warda2",
  "email": "[email protected]",
  "password": "$2b$10$BSEMsaytAXm.vaZKLDCuzu7LG4SPzvsXrLEOYK/3F5Fq4FGDdGuTO",
  "companyPosition": null,
  "companyName": null,
  "industry": null,
  "country": null,
  "currency": [],
  "profileImageUrl": null,
  "profileImageName": null,
  "role": "client",
  "isEmployee": false,
  "status": "Active",
  "firebaseToken": "fXxT5ZRQJSKMDOaXKOkWxF:APA91bGkZDWuceOGTd_hTwHhjCRKo4c6rbsyBSdFBL8l45oBxqKvpxHnjYLfUzAU6whHwGmpM07wasEw9nne4U8qRdhz_vf5hSJs3NLVZ94DsxtryxxIDM_WVM1A2E76mVJ39_46FMmU",
  "resetPasswordToken": null,
  "resetPasswordExpires": null,
  "emailVerificationToken": null,
  "emailTokenExpiry": null,
  "createdAt": {
    "$date": {
      "$numberLong": "1664437724388"
    }
  },
  "updatedAt": {
    "$date": {
      "$numberLong": "1666247312218"
    }
  },
  "deleted": true
},{
  "_id": {
    "$oid": "6346c87dca22a36cf627bd8b"
  },
  "name": "supervisor-hassan",
  "email": "[email protected]",
  "password": "$2b$10$VQ0MiXKlGKc0A0EmOr.4i.kImCQtjRqYQVNlURfoPfpfvszcHoI9.",
  "companyPosition": null,
  "companyName": null,
  "industry": null,
  "country": null,
  "currency": [],
  "profileImageUrl": null,
  "profileImageName": null,
  "role": "supervisor",
  "isEmployee": false,
  "status": "Active",
  "firebaseToken": null,
  "resetPasswordToken": null,
  "resetPasswordExpires": null,
  "emailVerificationToken": null,
  "emailTokenExpiry": null,
  "deleted": true,
  "createdAt": {
    "$date": {
      "$numberLong": "1665583229322"
    }
  },
  "updatedAt": {
    "$date": {
      "$numberLong": "1665583352347"
    }
  }
}

I want the nested object userId to be flattened using mongoose. How can I achieve this ? I want the data present in the userId object to be placed on the same top level object (not in any nested object). I just want to restructure the data which is being returned by my query.

2

Answers


  1. You would have to use Aggregate query if you want to modify the result.

    const ObjectId = require('mongoose').Types.ObjectId;
    
    
    const users = usersWorkspaceModel.aggregate([
      {
        $match: {
          workspaceId: ObjectId(workspaceId),
          userRole: 'supervisor',
        },
      },
      {
        $lookup: {
          from: 'users',
          localField: 'userId',
          foreignField: '_id',
          as: 'userId',
        },
      },
      {
        $set: {
          userId: { $first: '$userId' },
        },
      },
      {
        $project: {
          createdAt: 0,
          assignedBy: 0,
          updatedAt: 0,
          workspaceId: 0,
          _id: "$userId._id",
          name:"$userId.name",
          email: "$userId.email",
        },
      },
    ]);
    

    Or another solution is to keep your query and modify data directly in the server after response:

    let users = usersWorkspaceModel
        .find({
          workspaceId,
          userRole: 'supervisor',
        })
        .select({
          _id: 0,
          createdAt: 0,
          assignedBy: 0,
          updatedAt: 0,
          workspaceId: 0,
        })
        .populate({
          path: 'userId',
          select: ['_id', 'name', 'email'],
          mode: 'User',
        });
    
    users = users.map((item) => ({
      userRole: item.userRole,
      busy: item.busy,
      socketId: item.socketId,
      _id: item.userId._id,
      name: item.userId.name,
      email: item.userId.email,
    }))
    
    Login or Signup to reply.
  2. const ObjectId = require('mongoose').Types.ObjectId;
    
    
     const users = usersWorkspaceModel.aggregate([
        {
          $match: {
            workspaceId: ObjectId(workspaceId),
            userRole: 'supervisor',
          },
        },
        {
          $lookup: {
            from: 'users',
            localField: 'userId',
            foreignField: '_id',
            as: 'userId',
          },
        },
        {
          $unwind: '$userId',
        },
        {
          $replaceRoot: {
            newRoot: {
              $mergeObjects: ['$$ROOT', '$userId'],
            },
          },
        },
        {
          $project: {
            _id: 1,
            busy: 1,
            socketId: 1,
            name: 1,
            email: 1,
            userRole: 1,
          },
        },
      ]);
    

    The $unwind spreads the userId array into an object and $replaceRoot merges that object with the root Object. The $project selects the keys to output!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search