feat(home): AI 캐릭터 부족분을 랜덤 보충한다
This commit is contained in:
@@ -75,7 +75,10 @@ class HomeRecommendationFacade(
|
||||
includeAdultContents = includeAdult
|
||||
)
|
||||
.map { it.toItem() },
|
||||
aiCharacters = queryService.findAiCharacterRecommendations(limit = HOME_AI_CHARACTER_LIMIT).map { it.toItem() },
|
||||
aiCharacters = queryService.findAiCharacterRecommendations(
|
||||
limit = HOME_AI_CHARACTER_LIMIT,
|
||||
backfillRandom = true
|
||||
).map { it.toItem() },
|
||||
genreCreators = queryService.findGenreCreatorRecommendations(
|
||||
memberId = member?.id,
|
||||
includeAdultGenres = includeAdult,
|
||||
|
||||
@@ -775,6 +775,29 @@ class DefaultHomeRecommendationQueryRepository(
|
||||
.fetch()
|
||||
}
|
||||
|
||||
override fun findRandomAiCharacterRecommendationIds(
|
||||
excludeCharacterIds: List<Long>,
|
||||
limit: Int
|
||||
): List<Long> {
|
||||
val creatorMember = QMember("creatorMember")
|
||||
val randomTieBreaker = Expressions.numberTemplate(Double::class.java, "function('rand')")
|
||||
|
||||
return queryFactory
|
||||
.select(chatCharacter.id)
|
||||
.from(chatCharacter)
|
||||
.join(chatCharacter.creatorMember, creatorMember)
|
||||
.where(
|
||||
chatCharacter.isActive.isTrue,
|
||||
excludeAiCharacterCondition(excludeCharacterIds),
|
||||
creatorMember.isActive.isTrue,
|
||||
creatorMember.role.eq(MemberRole.CREATOR),
|
||||
creatorMember.memberKind.eq(MemberKind.AI_CHARACTER)
|
||||
)
|
||||
.orderBy(randomTieBreaker.asc())
|
||||
.limit(limit.toLong())
|
||||
.fetch()
|
||||
}
|
||||
|
||||
override fun findCheerCreatorRecommendationDetails(
|
||||
creatorIds: List<Long>,
|
||||
memberId: Long?
|
||||
@@ -1235,6 +1258,10 @@ class DefaultHomeRecommendationQueryRepository(
|
||||
return if (includeAdultLives) null else liveRoom.isAdult.isFalse
|
||||
}
|
||||
|
||||
private fun excludeAiCharacterCondition(excludeCharacterIds: List<Long>): BooleanExpression? {
|
||||
return if (excludeCharacterIds.isEmpty()) null else chatCharacter.id.notIn(excludeCharacterIds)
|
||||
}
|
||||
|
||||
private fun notBlockedCreatorCondition(memberId: Long?, creatorIdPath: Expression<Long>): BooleanExpression? {
|
||||
if (memberId == null) return null
|
||||
val blockMember = QBlockMember("recommendationBlockMember")
|
||||
|
||||
@@ -78,13 +78,23 @@ class HomeRecommendationQueryService(
|
||||
|
||||
fun findAiCharacterRecommendations(
|
||||
offset: Long = 0,
|
||||
limit: Int = DEFAULT_AI_CHARACTER_LIMIT
|
||||
limit: Int = DEFAULT_AI_CHARACTER_LIMIT,
|
||||
backfillRandom: Boolean = false
|
||||
): List<HomeAiCharacterRecommendationRecord> {
|
||||
val snapshots = findAiCharacterSnapshotsWithFallback(offset, limit)
|
||||
val detailsById = queryPort.findAiCharacterRecommendationDetails(snapshots.map { it.targetId })
|
||||
.associateBy { it.characterId }
|
||||
val snapshotDetails = snapshots.mapNotNull { detailsById[it.targetId] }
|
||||
|
||||
return snapshots.mapNotNull { detailsById[it.targetId] }
|
||||
if (!backfillRandom || snapshots.isEmpty() || snapshotDetails.size >= limit) return snapshotDetails
|
||||
|
||||
val randomIds = queryPort.findRandomAiCharacterRecommendationIds(
|
||||
excludeCharacterIds = snapshots.map { it.targetId },
|
||||
limit = limit - snapshotDetails.size
|
||||
)
|
||||
val randomDetailsById = queryPort.findAiCharacterRecommendationDetails(randomIds).associateBy { it.characterId }
|
||||
val randomDetails = randomIds.mapNotNull { randomDetailsById[it] }
|
||||
return (snapshotDetails + randomDetails).distinctBy { it.characterId }.take(limit)
|
||||
}
|
||||
|
||||
private fun findAiCharacterSnapshotsWithFallback(
|
||||
|
||||
@@ -58,6 +58,11 @@ interface HomeRecommendationQueryPort {
|
||||
|
||||
fun findAiCharacterRecommendationDetails(characterIds: List<Long>): List<HomeAiCharacterRecommendationRecord>
|
||||
|
||||
fun findRandomAiCharacterRecommendationIds(
|
||||
excludeCharacterIds: List<Long>,
|
||||
limit: Int
|
||||
): List<Long>
|
||||
|
||||
fun findCheerCreatorRecommendationDetails(
|
||||
creatorIds: List<Long>,
|
||||
memberId: Long? = null
|
||||
|
||||
Reference in New Issue
Block a user