...
This commit is contained in:
parent
d2a1f37f39
commit
00bba0bc39
@ -223,7 +223,22 @@ interface PostRepository : ReactiveMongoRepository<Post, String> {
|
|||||||
// @org.springframework.data.mongodb.repository.Query("{ '\$and': [ { 'posting': true }, { '\$expr': { '\$gte': [ { '\$strLenCP': '\$id' }, 4 ] } } ] }")
|
// @org.springframework.data.mongodb.repository.Query("{ '\$and': [ { 'posting': true }, { '\$expr': { '\$gte': [ { '\$strLenCP': '\$id' }, 4 ] } } ] }")
|
||||||
fun findAllByOrderByModifyTimeDesc(pageable: Pageable): Flux<Post>
|
fun findAllByOrderByModifyTimeDesc(pageable: Pageable): Flux<Post>
|
||||||
fun countByOrderByModifyTimeDesc(): Mono<Long>
|
fun countByOrderByModifyTimeDesc(): Mono<Long>
|
||||||
|
@Aggregation(pipeline = [
|
||||||
|
"{ \$sort: { modifyTime: -1 } }",
|
||||||
|
"{ \$group: { _id: { \$ifNull: [\"\$originId\", \"\$_id\"] }, post: { \$first: \"\$\$ROOT\" } } }",
|
||||||
|
"{ \$replaceRoot: { newRoot: \"\$post\" } }",
|
||||||
|
"{ \$match: { posting: true, postType: { \$ne: 'GIBBERISH' } } }",
|
||||||
|
"{ \$sort: { \"modifyTime\": -1 } }"
|
||||||
|
])
|
||||||
fun findTop5ByOrderByReadCountDesc(): Flux<Post>
|
fun findTop5ByOrderByReadCountDesc(): Flux<Post>
|
||||||
|
|
||||||
|
@Aggregation(pipeline = [
|
||||||
|
"{ \$sort: { modifyTime: -1 } }",
|
||||||
|
"{ \$group: { _id: { \$ifNull: [\"\$originId\", \"\$_id\"] }, post: { \$first: \"\$\$ROOT\" } } }",
|
||||||
|
"{ \$replaceRoot: { newRoot: \"\$post\" } }",
|
||||||
|
"{ \$match: { posting: true, postType: { \$ne: 'GIBBERISH' } } }",
|
||||||
|
"{ \$sort: { \"modifyTime\": -1 } }"
|
||||||
|
])
|
||||||
fun findTop5ByOrderByModifyTimeDesc(): Flux<Post>
|
fun findTop5ByOrderByModifyTimeDesc(): Flux<Post>
|
||||||
fun findByPostTypeOrderByModifyTimeDesc(postType: String): Flux<Post>
|
fun findByPostTypeOrderByModifyTimeDesc(postType: String): Flux<Post>
|
||||||
|
|
||||||
@ -302,7 +317,7 @@ interface PostRepository : ReactiveMongoRepository<Post, String> {
|
|||||||
fun countLatestUniqueOrigin(): Mono<AggregationCount> // 헬퍼 클래스로 매핑
|
fun countLatestUniqueOrigin(): Mono<AggregationCount> // 헬퍼 클래스로 매핑
|
||||||
|
|
||||||
@Aggregation(pipeline = [
|
@Aggregation(pipeline = [
|
||||||
"{ \$match: { \$or: [ { writer: ?0 }, { posting: true } ] } }",
|
"{ \$match: { \$and: [ { \$or: [ { writer: ?0 }, { posting: true } ] }, { 'postType': { \$ne: 'GIBBERISH' } } ] } }",
|
||||||
"{ \$sort: { modifyTime: -1 } }",
|
"{ \$sort: { modifyTime: -1 } }",
|
||||||
"{ \$group: { _id: { \$ifNull: [\"\$originId\", \"\$_id\"] }, post: { \$first: \"\$\$ROOT\" } } }",
|
"{ \$group: { _id: { \$ifNull: [\"\$originId\", \"\$_id\"] }, post: { \$first: \"\$\$ROOT\" } } }",
|
||||||
"{ \$replaceRoot: { newRoot: \"\$post\" } }",
|
"{ \$replaceRoot: { newRoot: \"\$post\" } }",
|
||||||
@ -311,7 +326,7 @@ interface PostRepository : ReactiveMongoRepository<Post, String> {
|
|||||||
fun findLatestUniqueForWriterPaginated(username: String, pageable: Pageable): Flux<Post>
|
fun findLatestUniqueForWriterPaginated(username: String, pageable: Pageable): Flux<Post>
|
||||||
|
|
||||||
@Aggregation(pipeline = [
|
@Aggregation(pipeline = [
|
||||||
"{ \$match: { \$or: [ { writer: ?0 }, { posting: true } ] } }",
|
"{ \$match: { \$and: [ { \$or: [ { writer: ?0 }, { posting: true } ] }, { 'postType': { \$ne: 'GIBBERISH' } } ] } }",
|
||||||
"{ \$group: { _id: { \$ifNull: [\"\$originId\", \"\$_id\"] } } }",
|
"{ \$group: { _id: { \$ifNull: [\"\$originId\", \"\$_id\"] } } }",
|
||||||
"{ \$count: \"totalCount\" }"
|
"{ \$count: \"totalCount\" }"
|
||||||
])
|
])
|
||||||
@ -319,41 +334,29 @@ interface PostRepository : ReactiveMongoRepository<Post, String> {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [수정] posting이 true인 문서만 필터링하는 $match 단계를 추가합니다.
|
* [수정] GIBBERISH 타입을 제외하고, posting이 true인 문서만 필터링하는 $match 단계를 추가합니다.
|
||||||
* [[[[[ FIXED LOGIC]]]]]
|
|
||||||
*/
|
*/
|
||||||
@Aggregation(pipeline = [
|
@Aggregation(pipeline = [
|
||||||
// 1. Sort ALL posts first to find the absolute most recent version of each.
|
|
||||||
"{ \$sort: { modifyTime: -1 } }",
|
"{ \$sort: { modifyTime: -1 } }",
|
||||||
// 2. Group by the original ID to get only the latest version.
|
|
||||||
"{ \$group: { _id: { \$ifNull: [\"\$originId\", \"\$_id\"] }, post: { \$first: \"\$\$ROOT\" } } }",
|
"{ \$group: { _id: { \$ifNull: [\"\$originId\", \"\$_id\"] }, post: { \$first: \"\$\$ROOT\" } } }",
|
||||||
// 3. Restore the post document structure.
|
|
||||||
"{ \$replaceRoot: { newRoot: \"\$post\" } }",
|
"{ \$replaceRoot: { newRoot: \"\$post\" } }",
|
||||||
// 4. NOW, filter this list of latest posts to show only the public ones.
|
"{ \$match: { posting: true, postType: { \$ne: 'GIBBERISH' } } }",
|
||||||
"{ \$match: { posting: true } }",
|
|
||||||
// 5. Finally, sort the remaining public posts for display.
|
|
||||||
"{ \$sort: { \"modifyTime\": -1 } }"
|
"{ \$sort: { \"modifyTime\": -1 } }"
|
||||||
])
|
])
|
||||||
fun findLatestUniquePublishedPaginated(pageable: Pageable): Flux<Post> // 메서드 이름 변경
|
fun findLatestUniquePublishedPaginated(pageable: Pageable): Flux<Post>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* '고유 최신 글' 중 공개된 글의 총 개수를 카운트합니다.
|
* '고유 최신 글' 중 공개된 글의 총 개수를 카운트합니다.
|
||||||
* [수정] posting이 true인 문서만 필터링하는 $match 단계를 추가합니다.
|
* [수정] GIBBERISH 타입을 제외하고, posting이 true인 문서만 필터링하는 $match 단계를 추가합니다.
|
||||||
* [[[[[FIXED LOGIC]]]]]
|
|
||||||
*/
|
*/
|
||||||
@Aggregation(pipeline = [
|
@Aggregation(pipeline = [
|
||||||
// 1. Sort ALL posts.
|
|
||||||
"{ \$sort: { modifyTime: -1 } }",
|
"{ \$sort: { modifyTime: -1 } }",
|
||||||
// 2. Group to get the latest version of each.
|
|
||||||
"{ \$group: { _id: { \$ifNull: [\"\$originId\", \"\$_id\"] }, post: { \$first: \"\$\$ROOT\" } } }",
|
"{ \$group: { _id: { \$ifNull: [\"\$originId\", \"\$_id\"] }, post: { \$first: \"\$\$ROOT\" } } }",
|
||||||
// 3. Restore the document.
|
|
||||||
"{ \$replaceRoot: { newRoot: \"\$post\" } }",
|
"{ \$replaceRoot: { newRoot: \"\$post\" } }",
|
||||||
// 4. Filter for public posts.
|
"{ \$match: { posting: true, postType: { \$ne: 'GIBBERISH' } } }",
|
||||||
"{ \$match: { posting: true } }",
|
|
||||||
// 5. Count the final result.
|
|
||||||
"{ \$count: \"totalCount\" }"
|
"{ \$count: \"totalCount\" }"
|
||||||
])
|
])
|
||||||
fun countLatestUniquePublished(): Mono<AggregationCount> // 메서드 이름 변경
|
fun countLatestUniquePublished(): Mono<AggregationCount>
|
||||||
|
|
||||||
fun findByWriterOrderByModifyTimeDesc(writer: String, pageable: Pageable): Flux<Post> // [신규 추가]
|
fun findByWriterOrderByModifyTimeDesc(writer: String, pageable: Pageable): Flux<Post> // [신규 추가]
|
||||||
|
|
||||||
@ -383,6 +386,10 @@ interface PostRepository : ReactiveMongoRepository<Post, String> {
|
|||||||
"{ \$match: { _id: { \$ne: \"\" } } }"
|
"{ \$match: { _id: { \$ne: \"\" } } }"
|
||||||
])
|
])
|
||||||
fun findDistinctTags(): Flux<org.bson.Document> // 반환 타입을 Document로 변경
|
fun findDistinctTags(): Flux<org.bson.Document> // 반환 타입을 Document로 변경
|
||||||
|
|
||||||
|
// [신규 추가] GIBBERISH 제외하고 조회
|
||||||
|
fun findByPostTypeNotOrderByModifyTimeDesc(postType: String, pageable: Pageable): Flux<Post>
|
||||||
|
fun countByPostTypeNot(postType: String): Mono<Long>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -401,26 +408,30 @@ class PostManager(
|
|||||||
return postRepository.deleteById(postId)
|
return postRepository.deleteById(postId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// [수정] 익명 사용자용 목록 조회
|
// [수정] 익명 사용자용 목록 조회 (Aggregation 사용)
|
||||||
fun findLatestUniquePaginated(pageable: Pageable) : Mono<List<Post>> {
|
fun findLatestUniquePaginated(pageable: Pageable) : Mono<List<Post>> {
|
||||||
return postRepository.findByPostingIsTrueOrderByModifyTimeDesc(pageable)
|
return postRepository.findLatestUniquePublishedPaginated(pageable)
|
||||||
.collectList()
|
.collectList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// [수정] 익명 사용자용 글 개수
|
// [수정] 익명 사용자용 글 개수 (Aggregation 사용)
|
||||||
fun countLatestUnique(): Mono<Long> {
|
fun countLatestUnique(): Mono<Long> {
|
||||||
return postRepository.countByPostingIsTrue()
|
return postRepository.countLatestUniquePublished()
|
||||||
|
.map { it.totalCount }
|
||||||
|
.switchIfEmpty(Mono.just(0L))
|
||||||
}
|
}
|
||||||
|
|
||||||
// [수정] '글쓰기' 권한 사용자용 목록 조회
|
// [수정] '글쓰기' 권한 사용자용 목록 조회 (Aggregation 사용)
|
||||||
fun findLatestUniqueForWriter(username: String, pageable: Pageable) : Mono<List<Post>> {
|
fun findLatestUniqueForWriter(username: String, pageable: Pageable) : Mono<List<Post>> {
|
||||||
return postRepository.findByPostingIsTrueOrWriterOrderByModifyTimeDesc(username, pageable)
|
return postRepository.findLatestUniqueForWriterPaginated(username, pageable)
|
||||||
.collectList()
|
.collectList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// [수정] '글쓰기' 권한 사용자용 글 개수
|
// [수정] '글쓰기' 권한 사용자용 글 개수 (Aggregation 사용)
|
||||||
fun countLatestUniqueForWriter(username: String): Mono<Long> {
|
fun countLatestUniqueForWriter(username: String): Mono<Long> {
|
||||||
return postRepository.countByPostingIsTrueOrWriter(username)
|
return postRepository.countLatestUniqueForWriter(username)
|
||||||
|
.map { it.totalCount }
|
||||||
|
.switchIfEmpty(Mono.just(0L))
|
||||||
}
|
}
|
||||||
|
|
||||||
// [수정] 익명 사용자용 인기글
|
// [수정] 익명 사용자용 인기글
|
||||||
@ -541,11 +552,10 @@ class PostManager(
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 인증된 사용자를 위한 메서드 (모든 버전 조회)
|
* 인증된 사용자를 위한 메서드 (모든 버전 조회, GIBBERISH 제외)
|
||||||
* [FIX]: Change return type to Mono<List<Post>> and remove the blocking call.
|
|
||||||
*/
|
*/
|
||||||
fun findAllVersionsPaginated(pageable :Pageable) : Mono<List<Post>> {
|
fun findAllVersionsPaginated(pageable :Pageable) : Mono<List<Post>> {
|
||||||
return postRepository.findAllByOrderByModifyTimeDesc(pageable)
|
return postRepository.findByPostTypeNotOrderByModifyTimeDesc(PostType.GIBBERISH.name, pageable)
|
||||||
.map { post ->
|
.map { post ->
|
||||||
// 1. 제목을 UTF-8로 디코딩합니다.
|
// 1. 제목을 UTF-8로 디코딩합니다.
|
||||||
post.title = post.title?.let { URLDecoder.decode(it, "UTF-8") } ?: ""
|
post.title = post.title?.let { URLDecoder.decode(it, "UTF-8") } ?: ""
|
||||||
@ -560,32 +570,13 @@ class PostManager(
|
|||||||
.collectList()
|
.collectList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * 익명 사용자를 위한 메서드 (고유 최신 글 페이지네이션 조회)
|
|
||||||
// * [FIX]: This function should already be correct from the previous step.
|
|
||||||
// */
|
|
||||||
// fun findLatestUniquePaginated(pageable: Pageable) : Mono<List<Post>> { // <-- Should already return Mono
|
|
||||||
// return postRepository.findLatestUniquePublishedPaginated(pageable)
|
|
||||||
// .collectList()
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 인증된 사용자가 보는 글의 총 개수
|
* 인증된 사용자가 보는 글의 총 개수 (GIBBERISH 제외)
|
||||||
*/
|
*/
|
||||||
fun countAllVersions(): Mono<Long> {
|
fun countAllVersions(): Mono<Long> {
|
||||||
return postRepository.countByOrderByModifyTimeDesc()
|
return postRepository.countByPostTypeNot(PostType.GIBBERISH.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
|
||||||
// * 익명 사용자가 보는 글의 총 개수
|
|
||||||
// */
|
|
||||||
// fun countLatestUnique(): Mono<Long> {
|
|
||||||
// // AggregationCount(totalCount=N) 객체에서 Long 값만 추출합니다. 결과가 없으면 0L을 반환합니다.
|
|
||||||
// return postRepository.countLatestUniquePublished()
|
|
||||||
// .map { it.totalCount }
|
|
||||||
// .switchIfEmpty(Mono.just(0L))
|
|
||||||
// }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 좋아요 카운트를 1 증가시키고, JS에서 즉시 업데이트할 수 있도록 *업데이트된* 문서를 반환합니다.
|
* 좋아요 카운트를 1 증가시키고, JS에서 즉시 업데이트할 수 있도록 *업데이트된* 문서를 반환합니다.
|
||||||
*/
|
*/
|
||||||
@ -634,13 +625,10 @@ class PostManager(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 홈 화면은 이제 "익명 사용자용 최신 글"의 0번 페이지, 8개 아이템을 명시적으로 요청합니다.
|
* 홈 화면은 이제 "익명 사용자용 최신 글"의 0번 페이지, 8개 아이템을 명시적으로 요청합니다.
|
||||||
* [FIX]: Return Mono<List<Post>> to match the updated callee.
|
|
||||||
*/
|
*/
|
||||||
fun find8() : Mono<List<Post>> { // <-- 3. Change return type to Mono<List<Post>>
|
fun find8() : Mono<List<Post>> {
|
||||||
// 홈 화면은 항상 0번 페이지의 8개 아이템을 요청합니다.
|
|
||||||
val pageRequest = PageRequest.of(0, 8) // Page 0, Size 8
|
val pageRequest = PageRequest.of(0, 8) // Page 0, Size 8
|
||||||
// 하드코딩된 쿼리 대신, 익명사용자용 페이지네이션 메서드를 호출합니다.
|
return this.findLatestUniquePaginated(pageRequest)
|
||||||
return this.findLatestUniquePaginated(pageRequest) // <-- 4. This now correctly returns the Mono
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun save(post: Post): Mono<Post> {
|
fun save(post: Post): Mono<Post> {
|
||||||
@ -674,30 +662,6 @@ class PostManager(
|
|||||||
p
|
p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// // [신규 추가] 익명 사용자용 인기글
|
|
||||||
// fun getTop5UniquePublishedByViews(): Flux<Post> {
|
|
||||||
// return postRepository.findTop5UniquePublishedByReadCountDesc().map { p ->
|
|
||||||
// p.title = URLDecoder.decode(p.title, "UTF-8")
|
|
||||||
// if (p.title?.isEmpty() == true) {
|
|
||||||
// p.title = "무제(無題)"
|
|
||||||
// }
|
|
||||||
// println("${p.id} p.posting >> ${p.posting}")
|
|
||||||
// p
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // [신규 추가] 익명 사용자용 최신글
|
|
||||||
// fun getRecent5UniquePublished(): Flux<Post> {
|
|
||||||
// return postRepository.findTop5UniquePublishedByModifyTimeDesc().map { p ->
|
|
||||||
// p.title = URLDecoder.decode(p.title, "UTF-8")
|
|
||||||
// if (p.title?.isEmpty() == true) {
|
|
||||||
// p.title = "무제(無題)"
|
|
||||||
// }
|
|
||||||
// p
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user