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.
CodePudding user response:
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!
CodePudding user response:
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,
}))