2

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
  • Can you add sample documents for the related collections? Commented Oct 20, 2022 at 6:53
  • I have added sample documents ! Commented Oct 20, 2022 at 7:02

2 Answers 2

1
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!

Sign up to request clarification or add additional context in comments.

Comments

0

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,
}))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.