如何使用嵌套查找查询?

huangapple go评论70阅读模式
英文:

how to use nested lookup query?

问题

I have two collections "new_users" and "workspaces". I am trying to do a lookup query but it gives only an 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 the userData field. What am I doing wrong here?

英文:

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?

答案1

得分: 1

以下是翻译好的内容:

问题是你试图在查找阶段匹配一个字符串和一个对象ID,因此它返回一个空数组作为结果。

你可以要么更改你的模型,使userID成为Types.ObjectId,要么在聚合阶段进行管理。一个示例是在管道阶段将字符串字段转换为对象ID字段。

例如,你可以使用$addFields在查找之前将字符串字段转换为对象ID字段:

db.workspaces.aggregate([
  {
    $unwind: "$users"
  },
  {
    $addFields: {
      "users.userID": {
        $toObjectId: "$users.userID"
      }
    }
  },
  {
    $lookup: {
      from: "new_users",
      localField: "users.userID",
      foreignField: "_id",
      as: "userData"
    }
  }
])

示例播放场地

英文:

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"
    }
  }
])

sample playground

huangapple
  • 本文由 发表于 2023年5月11日 03:54:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/76222148.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定