Skip to content

Commit

Permalink
Refactor: research search (#201)
Browse files Browse the repository at this point in the history
  • Loading branch information
huGgW authored Mar 2, 2024
1 parent 0ee8536 commit 385476e
Show file tree
Hide file tree
Showing 10 changed files with 208 additions and 128 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package com.wafflestudio.csereal.core.research.api

import com.wafflestudio.csereal.common.aop.AuthenticatedStaff
import com.wafflestudio.csereal.core.research.dto.*
import com.wafflestudio.csereal.common.properties.LanguageType
import com.wafflestudio.csereal.core.research.dto.LabDto
import com.wafflestudio.csereal.core.research.dto.LabUpdateRequest
import com.wafflestudio.csereal.core.research.dto.ResearchDto
import com.wafflestudio.csereal.core.research.dto.ResearchGroupResponse
import com.wafflestudio.csereal.core.research.service.ResearchSearchService
import com.wafflestudio.csereal.core.research.service.ResearchService
import jakarta.validation.Valid
import jakarta.validation.constraints.Positive
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
import org.springframework.web.multipart.MultipartFile
Expand Down Expand Up @@ -136,13 +141,28 @@ class ResearchController(
@GetMapping("/search/top")
fun searchTop(
@RequestParam(required = true) keyword: String,
@RequestParam(required = true) number: Int
) = researchSearchService.searchTopResearch(keyword, number)
@RequestParam(required = true) @Valid @Positive number: Int,
@RequestParam(required = true, defaultValue = "ko") language: String,
@RequestParam(required = false, defaultValue = "30") @Valid @Positive amount: Int
) = researchSearchService.searchTopResearch(
keyword,
LanguageType.makeStringToLanguageType(language),
number,
amount
)

@GetMapping("/search")
fun searchPage(
@RequestParam(required = true) keyword: String,
@RequestParam(required = true) pageSize: Int,
@RequestParam(required = true) pageNum: Int
) = researchSearchService.searchResearch(keyword, pageSize, pageNum)
@RequestParam(required = true) pageNum: Int,
@RequestParam(required = true, defaultValue = "ko") language: String,
@RequestParam(required = false, defaultValue = "30") @Valid @Positive amount: Int
) = researchSearchService.searchResearch(
keyword,
LanguageType.makeStringToLanguageType(language),
pageSize,
pageNum,
amount
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.wafflestudio.csereal.core.research.api.res

import com.wafflestudio.csereal.core.research.database.ResearchSearchEntity

data class ResearchSearchResBody(
val results: List<ResearchSearchResElement>,
val total: Long
) {
companion object {
fun of(
researches: List<ResearchSearchEntity>,
keyword: String,
amount: Int,
total: Long
) = ResearchSearchResBody(
results = researches.map {
ResearchSearchResElement.of(it, keyword, amount)
},
total = total
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.wafflestudio.csereal.core.research.api.res

import com.wafflestudio.csereal.common.CserealException
import com.wafflestudio.csereal.common.properties.LanguageType
import com.wafflestudio.csereal.common.utils.substringAroundKeyword
import com.wafflestudio.csereal.core.research.database.ResearchSearchEntity
import com.wafflestudio.csereal.core.research.database.ResearchSearchType

data class ResearchSearchResElement(
val id: Long,
val language: String,
val name: String,
val researchType: ResearchSearchType,
val partialDescription: String,
val boldStartIdx: Int,
val boldEndIdx: Int
) {
companion object {
fun of(
researchSearchEntity: ResearchSearchEntity,
keyword: String,
amount: Int
): ResearchSearchResElement =
when {
researchSearchEntity.research != null &&
researchSearchEntity.lab == null &&
researchSearchEntity.conferenceElement == null
-> researchSearchEntity.research!!.let {
val (startIdx, partialDesc) = substringAroundKeyword(
keyword,
researchSearchEntity.content,
amount
)
ResearchSearchResElement(
id = it.id,
name = it.name,
language = it.language.let { ln -> LanguageType.makeLowercase(ln) },
researchType = ResearchSearchType.RESEARCH,
partialDescription = partialDesc,
boldStartIdx = startIdx ?: 0,
boldEndIdx = startIdx?.plus(keyword.length) ?: 0
)
}

researchSearchEntity.lab != null &&
researchSearchEntity.research == null &&
researchSearchEntity.conferenceElement == null
-> researchSearchEntity.lab!!.let {
val (startIdx, partialDesc) = substringAroundKeyword(
keyword,
researchSearchEntity.content,
amount
)
ResearchSearchResElement(
id = it.id,
name = it.name,
language = it.language.let { ln -> LanguageType.makeLowercase(ln) },
researchType = ResearchSearchType.LAB,
partialDescription = partialDesc,
boldStartIdx = startIdx ?: 0,
boldEndIdx = startIdx?.plus(keyword.length) ?: 0
)
}

researchSearchEntity.conferenceElement != null &&
researchSearchEntity.research == null &&
researchSearchEntity.lab == null
-> researchSearchEntity.conferenceElement!!.let {
val (startIdx, partialDesc) = substringAroundKeyword(
keyword,
researchSearchEntity.content,
amount
)
ResearchSearchResElement(
id = it.id,
name = it.name,
language = it.language.let { ln -> LanguageType.makeLowercase(ln) },
researchType = ResearchSearchType.CONFERENCE,
partialDescription = partialDesc,
boldStartIdx = startIdx ?: 0,
boldEndIdx = startIdx?.plus(keyword.length) ?: 0
)
}

else -> throw CserealException.Csereal401(
"ResearchSearchEntity의 연결이 올바르지 않습니다."
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.wafflestudio.csereal.core.research.database

import com.wafflestudio.csereal.common.config.BaseTimeEntity
import com.wafflestudio.csereal.common.properties.LanguageType
import com.wafflestudio.csereal.common.utils.cleanTextFromHtml
import com.wafflestudio.csereal.core.conference.database.ConferenceEntity
import jakarta.persistence.*
Expand All @@ -10,6 +11,9 @@ class ResearchSearchEntity(
@Column(columnDefinition = "TEXT")
var content: String,

@Enumerated(value = EnumType.STRING)
val language: LanguageType,

@OneToOne
@JoinColumn(name = "research_id")
val research: ResearchEntity? = null,
Expand All @@ -26,20 +30,23 @@ class ResearchSearchEntity(
fun create(research: ResearchEntity): ResearchSearchEntity {
return ResearchSearchEntity(
content = createContent(research),
language = research.language,
research = research
)
}

fun create(lab: LabEntity): ResearchSearchEntity {
return ResearchSearchEntity(
content = createContent(lab),
language = lab.language,
lab = lab
)
}

fun create(conference: ConferenceEntity): ResearchSearchEntity {
return ResearchSearchEntity(
content = createContent(conference),
language = conference.language,
conferenceElement = conference
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package com.wafflestudio.csereal.core.research.database

import com.querydsl.jpa.impl.JPAQuery
import com.querydsl.jpa.impl.JPAQueryFactory
import com.wafflestudio.csereal.common.properties.LanguageType
import com.wafflestudio.csereal.common.repository.CommonRepository
import com.wafflestudio.csereal.common.utils.exchangePageNum
import com.wafflestudio.csereal.core.conference.database.QConferenceEntity.conferenceEntity
import com.wafflestudio.csereal.core.research.database.QLabEntity.labEntity
import com.wafflestudio.csereal.core.research.database.QResearchEntity.researchEntity
Expand All @@ -13,25 +15,27 @@ import org.springframework.stereotype.Repository
interface ResearchSearchRepository : JpaRepository<ResearchSearchEntity, Long>, ResearchSearchRepositoryCustom

interface ResearchSearchRepositoryCustom {
fun searchTopResearch(keyword: String, number: Int): List<ResearchSearchEntity>

fun searchResearch(keyword: String, pageSize: Int, pageNum: Int): Pair<List<ResearchSearchEntity>, Long>
fun searchResearch(
keyword: String,
language: LanguageType,
pageSize: Int,
pageNum: Int
): Pair<List<ResearchSearchEntity>, Long>
}

@Repository
class ResearchSearchRepositoryCustomImpl(
private val queryFactory: JPAQueryFactory,
private val commonRepository: CommonRepository
) : ResearchSearchRepositoryCustom {
override fun searchTopResearch(keyword: String, number: Int): List<ResearchSearchEntity> {
return searchQuery(keyword)
.limit(number.toLong())
.fetch()
}

override fun searchResearch(keyword: String, pageSize: Int, pageNum: Int): Pair<List<ResearchSearchEntity>, Long> {
val query = searchQuery(keyword)
val total = getSearchCount(keyword)
override fun searchResearch(
keyword: String,
language: LanguageType,
pageSize: Int,
pageNum: Int
): Pair<List<ResearchSearchEntity>, Long> {
val query = searchQuery(keyword, language)
val total = getSearchCount(keyword, language)

val validPageNum = exchangePageNum(pageSize, pageNum, total)
val validOffset = (if (validPageNum >= 1) validPageNum - 1 else 0) * pageSize.toLong()
Expand All @@ -43,7 +47,7 @@ class ResearchSearchRepositoryCustomImpl(
return queryResult to total
}

fun searchQuery(keyword: String): JPAQuery<ResearchSearchEntity> {
fun searchQuery(keyword: String, language: LanguageType): JPAQuery<ResearchSearchEntity> {
val searchDoubleTemplate = commonRepository.searchFullSingleTextTemplate(
keyword,
researchSearchEntity.content
Expand All @@ -64,11 +68,12 @@ class ResearchSearchRepositoryCustomImpl(
conferenceEntity
).fetchJoin()
.where(
searchDoubleTemplate.gt(0.0)
searchDoubleTemplate.gt(0.0),
researchSearchEntity.language.eq(language)
)
}

fun getSearchCount(keyword: String): Long {
fun getSearchCount(keyword: String, language: LanguageType): Long {
val searchDoubleTemplate = commonRepository.searchFullSingleTextTemplate(
keyword,
researchSearchEntity.content
Expand All @@ -80,15 +85,8 @@ class ResearchSearchRepositoryCustomImpl(
).from(
researchSearchEntity
).where(
searchDoubleTemplate.gt(0.0)
searchDoubleTemplate.gt(0.0),
researchSearchEntity.language.eq(language)
).fetchOne()!!
}

fun exchangePageNum(pageSize: Int, pageNum: Int, total: Long): Int {
return if ((pageNum - 1) * pageSize < total) {
pageNum
} else {
Math.ceil(total.toDouble() / pageSize).toInt()
}
}
}

This file was deleted.

This file was deleted.

This file was deleted.

Loading

0 comments on commit 385476e

Please sign in to comment.