@@ -7,16 +7,23 @@ import com.wafflestudio.snutt.theme.data.ThemeMarketInfo
77import com.wafflestudio.snutt.theme.data.ThemeOrigin
88import com.wafflestudio.snutt.theme.data.ThemeStatus
99import com.wafflestudio.snutt.theme.data.TimetableTheme
10+ import com.wafflestudio.snutt.theme.dto.TimetableThemeDto
1011import kotlinx.coroutines.reactive.awaitSingle
1112import kotlinx.coroutines.reactor.awaitSingleOrNull
13+ import org.springframework.data.domain.Sort
1214import org.springframework.data.mapping.div
1315import org.springframework.data.mapping.toDotPath
1416import org.springframework.data.mongodb.core.ReactiveMongoTemplate
17+ import org.springframework.data.mongodb.core.aggregation.Aggregation
18+ import org.springframework.data.mongodb.core.aggregation.ArrayOperators
19+ import org.springframework.data.mongodb.core.aggregation.ConvertOperators
20+ import org.springframework.data.mongodb.core.aggregation.TypedAggregation
1521import org.springframework.data.mongodb.core.exists
1622import org.springframework.data.mongodb.core.find
1723import org.springframework.data.mongodb.core.query.Query
1824import org.springframework.data.mongodb.core.query.Update
1925import org.springframework.data.mongodb.core.query.and
26+ import org.springframework.data.mongodb.core.query.inValues
2027import org.springframework.data.mongodb.core.query.regex
2128import org.springframework.data.mongodb.core.updateFirst
2229
@@ -36,11 +43,26 @@ interface TimetableThemeCustomRepository {
3643 ): Boolean
3744
3845 suspend fun addDownloadCount (id : String )
46+
47+ suspend fun findOriginalThemesByUserIds (
48+ userIds : List <String >,
49+ page : Int ,
50+ ): List <TimetableTheme >
3951}
4052
4153class TimetableThemeCustomRepositoryImpl (
4254 private val reactiveMongoTemplate : ReactiveMongoTemplate ,
4355) : TimetableThemeCustomRepository {
56+ companion object {
57+ private const val EFFECTIVE_THEME_ID_ALIAS = " effectiveThemeId"
58+ private const val THEME_DETAILS_ALIAS = " themeDetails"
59+ private const val DOWNLOADED_THEMES_ALIAS = " downloadedThemes"
60+ private const val PUBLISHED_THEMES_ALIAS = " publishedThemes"
61+ private const val COMBINED_THEMES_ALIAS = " combinedThemes"
62+ private const val DOC_ALIAS = " doc"
63+ private const val ID_FIELD = " _id"
64+ }
65+
4466 override suspend fun findLastChild (
4567 userId : String ,
4668 name : String ,
@@ -88,4 +110,59 @@ class TimetableThemeCustomRepositoryImpl(
88110 Update ().inc((TimetableTheme ::publishInfo / ThemeMarketInfo ::downloads).toDotPath(), 1 ),
89111 ).awaitSingle()
90112 }
113+
114+ override suspend fun findOriginalThemesByUserIds (
115+ userIds : List <String >,
116+ page : Int ,
117+ ): List <TimetableTheme > {
118+ val downloadedOriginStages =
119+ arrayOf(
120+ Aggregation .match(
121+ TimetableThemeDto ::userId.inValues(userIds)
122+ .and (TimetableThemeDto ::status).isEqualTo(ThemeStatus .DOWNLOADED ),
123+ ),
124+ Aggregation .project()
125+ .and (ConvertOperators .ToObjectId .toObjectId(" $${TimetableTheme ::origin.div(ThemeOrigin ::originId).toDotPath()} " ))
126+ .`as `(EFFECTIVE_THEME_ID_ALIAS ),
127+ Aggregation .lookup()
128+ .from(reactiveMongoTemplate.getCollectionName(TimetableTheme ::class .java))
129+ .localField(EFFECTIVE_THEME_ID_ALIAS )
130+ .foreignField(ID_FIELD )
131+ .`as `(THEME_DETAILS_ALIAS ),
132+ Aggregation .unwind(THEME_DETAILS_ALIAS ),
133+ Aggregation .replaceRoot(THEME_DETAILS_ALIAS ),
134+ )
135+ val publishedStages =
136+ arrayOf(
137+ Aggregation .match(
138+ TimetableTheme ::userId.inValues(userIds)
139+ .and (TimetableTheme ::status).isEqualTo(ThemeStatus .PUBLISHED ),
140+ ),
141+ )
142+ val facetOperation =
143+ Aggregation .facet()
144+ .and (* downloadedOriginStages).`as `(DOWNLOADED_THEMES_ALIAS )
145+ .and (* publishedStages).`as `(PUBLISHED_THEMES_ALIAS )
146+ val combinedAggregation =
147+ TypedAggregation .newAggregation(
148+ TimetableTheme ::class .java,
149+ facetOperation,
150+ Aggregation .project()
151+ .and (ArrayOperators .ConcatArrays .arrayOf(" $$DOWNLOADED_THEMES_ALIAS " ).concat(" $$PUBLISHED_THEMES_ALIAS " ))
152+ .`as `(COMBINED_THEMES_ALIAS ),
153+ Aggregation .unwind(" $$COMBINED_THEMES_ALIAS " ),
154+ Aggregation .replaceRoot(" $$COMBINED_THEMES_ALIAS " ),
155+ Aggregation .group(ID_FIELD )
156+ .first(Aggregation .ROOT ).`as `(DOC_ALIAS ),
157+ Aggregation .replaceRoot(" $$DOC_ALIAS " ),
158+ Aggregation .sort(
159+ Sort .Direction .DESC ,
160+ TimetableTheme ::publishInfo.div(ThemeMarketInfo ::downloads).toDotPath(),
161+ ),
162+ )
163+ return reactiveMongoTemplate.aggregate(
164+ combinedAggregation,
165+ TimetableTheme ::class .java,
166+ ).skip((page - 1 ) * 10L ).take(10 ).collectList().awaitSingle()
167+ }
91168}
0 commit comments