我需要计算用户之间的共同好友,目前工作正常,但我认为它不适用于拥有大量粉丝的用户,加载和比较需要很长时间。请建议我好的数据库设计/查询(如果需要)。 我已经创建了表并有一个这样的查询:
表:
export enum FollowStatus {
REQUESTED = "REQUESTED",
APPROVED = "APPROVED",
DECLINED = "DECLINED"
}
@Entity("followers")
export class Followers {
@PrimaryGeneratedColumn()
@Property()
id: number;
@Property()
@Column()
followerId: string;
@ManyToOne(() => Users, { eager: true })
@JoinColumn({ name: "followerId" })
follower: Users;
@Property()
@Column()
followedId: string;
@ManyToOne(() => Users, { eager: true })
@JoinColumn({ name: "followedId" })
followed: Users;
@Column({
type: "enum",
enum: FollowStatus,
default: FollowStatus.REQUESTED
})
@Property()
status: FollowStatus;
}
查询:
async getFollowers(userId: string, page: number, limit: number) {
const builder: SelectQueryBuilder<Followers> = this.createQueryBuilder("followers")
.where("followers.followedId = :userId", { userId })
.andWhere("followers.status = :status", { status: "APPROVED" })
.leftJoinAndSelect("followers.follower", "follower")
.leftJoinAndSelect("follower.followers", "followerFollowers")
.take(limit)
.skip((page - 1) * limit);
const followers = await builder.getManyAndCount();
return followers;
}
主要功能:
async getFollowers(userId: string, page: number, limit: number) {
page = page || DEFAULT_PAGE_NUMBER;
limit = limit || DEFAULT_PAGE_SIZE;
const followers = await this.followersRepository.getFollowers(userId, page, limit);
const myFollowers = followers[0].map((follower) => follower.followerId);
const response: SearchResponse<FollowerUsersInterface> = {
data: await Promise.all(
followers[0].map(async (user) => {
const isFollowing = user.follower.followers.findIndex((follower) => follower.followerId == userId);
const userFollowers = user.follower.followers;
// count mutual followers, exluding the user itself
const mutualFollowersCount = userFollowers.filter((follower) => {
if (follower.followerId !== user.followerId) {
return myFollowers.some((myFollower) => myFollower === follower.followerId && follower.status === FollowStatus.APPROVED);
}
}).length;
return {
isFollowing: isFollowing > -1,
userId: user.follower.id,
userName: user.follower.userName,
profilePic: await this.s3.getSignedUrl(user.follower.profilePic),
mutualFollowers: mutualFollowersCount
} as FollowerUsersInterface;
})
),
totalCount: followers[1]
};
return response;
}
示例数据库记录:
# id status followerId followedId
20 APPROVED 3 PBpq
22 APPROVED 1 PBpq
24 APPROVED 2 PBpq
25 APPROVED PBpq 2
26 APPROVED 1 2
28 APPROVED INOr PBpq
29 APPROVED 2NAo PBpq
34 APPROVED 1 2NAo
改变了方法,现在我正在获取用户的关注者列表
async getFollowers(userId: string, page: number, limit: number) {
const builder: SelectQueryBuilder<Followers> = this.createQueryBuilder("followers")
.where("followers.followedId = :userId", { userId })
.andWhere("followers.status = :status", { status: "APPROVED" })
.leftJoinAndSelect("followers.follower", "follower")
.take(limit)
.skip((page - 1) * limit);
const followers = await builder.getManyAndCount();
return followers;
},
然后逐一迭代并获得共同关注者列表:
async getMutualFollowersCount(myuserId: string, userId: string): Promise<number> {
const subQuery: SelectQueryBuilder<Followers> = this.createQueryBuilder("subFollowers")
.where("subFollowers.followedId = :myuserId", { myuserId })
.andWhere("subFollowers.status = :status", { status: "APPROVED" })
.select("subFollowers.followerId");
const builder: SelectQueryBuilder<Followers> = this.createQueryBuilder("followers")
.where("followers.followerId = :userId", { userId })
.andWhere("followers.status = :status", { status: "APPROVED" })
.andWhere(`followers.followedId IN (${subQuery.getQuery()})`)
.setParameters(subQuery.getParameters());
const mutualFollowersCount = await builder.getCount();
return mutualFollowersCount;
},