I have two collections "new_users" and "workspaces". I am trying to do a lookup query but it gives only empty array in the expected field.
My 'new_users' collection:
export class UserEntity {
@Prop({ required: false, type: Types.ObjectId, default: () => new ObjectId() })
_id?: Types.ObjectId;
@Expose()
@Prop({ default: '', trim: true, text: true })
firstName: string;
@Expose()
@Prop({ default: '', trim: true, text: true })
lastName: string;
}
My "workspaces" collection:
export class WorkspaceUsers {
@Expose()
@Prop({ type: () => [WorkspaceUserGroup] })
groups: WorkspaceUserGroup[];
@Expose()
@Prop({ required: true, type: String, enum: WorkspaceRoleEnum })
workSpaceRole: WorkspaceRoleEnum;
@Expose()
@Prop({ required: true, type: String, ref: () => UserEntity })
userID: string;
}
export class WorkspaceEntity {
@Prop({ required: false, type: Types.ObjectId, default: () => new ObjectId() })
_id?: Types.ObjectId;
@Expose()
@IsString()
@IsDefined()
@Prop({ required: true, trim: true })
name: string;
@Expose()
@IsOptional()
@IsArray()
@ValidateNested({ each: true })
@Type(() => WorkspaceUsers)
@Prop({ required: false, type: () => [WorkspaceUsers], default: [] })
users: WorkspaceUsers[];
}
Now I want to run a lookup query in my workspaces model like this:
const aggregationQuery: PipelineStage[] = [];
aggregationQuery.push({
$unwind: '$users',
});
aggregationQuery.push({
$lookup: {
from: 'new_users',
localField: 'users.userID',
foreignField: '_id',
as: 'userData',
},
});
It is returning an empty array in userData field. What am I doing wrong here?
The problem is you are trying to match a string and an object id in the lookup stage so it returns an empty array as a result
you can either change your model so that userID
is Types.ObjectId
or you can manage that in the aggregation stage as well. An example is to convert the string field to object id field in a pipeline stage
for example you can use $addFields
to convert the string field to object id field before doing the lookup
db.workspaces.aggregate([
{
$unwind: "$users"
},
{
$addFields: {
"users.userID": {
$toObjectId: "$users.userID"
}
}
},
{
$lookup: {
from: "new_users",
localField: "users.userID",
foreignField: "_id",
as: "userData"
}
}
])