@@ -3,40 +3,17 @@ package no.java.conf.service
33import arrow.core.raise.Raise
44import arrow.core.raise.ensure
55import arrow.core.raise.ensureNotNull
6- import com.jillesvangurp.jsondsl.json
7- import com.jillesvangurp.ktsearch.Aggregations
8- import com.jillesvangurp.ktsearch.SearchClient
9- import com.jillesvangurp.ktsearch.count
10- import com.jillesvangurp.ktsearch.parseHits
11- import com.jillesvangurp.ktsearch.parsedBuckets
12- import com.jillesvangurp.ktsearch.search
13- import com.jillesvangurp.ktsearch.termsResult
14- import com.jillesvangurp.searchdsls.querydsl.SearchDSL
15- import com.jillesvangurp.searchdsls.querydsl.TermsAgg
16- import com.jillesvangurp.searchdsls.querydsl.agg
17- import com.jillesvangurp.searchdsls.querydsl.bool
18- import com.jillesvangurp.searchdsls.querydsl.exists
19- import com.jillesvangurp.searchdsls.querydsl.nested
20- import com.jillesvangurp.searchdsls.querydsl.simpleQueryString
21- import com.jillesvangurp.searchdsls.querydsl.terms
226import io.github.oshai.kotlinlogging.KotlinLogging
23- import no.java.conf.model.AggregationsNotFound
247import no.java.conf.model.ApiError
258import no.java.conf.model.IndexNotReady
269import no.java.conf.model.SearchMissing
27- import no.java.conf.model.search.AggregateResponse
28- import no.java.conf.model.search.FormatAggregate
29- import no.java.conf.model.search.LanguageAggregate
3010import no.java.conf.model.search.SearchResponse
31- import no.java.conf.model.search.SessionResponse
3211import no.java.conf.model.search.TextSearchRequest
3312import no.java.conf.model.search.VideoSearchResponse
34- import no.java.conf.model.search.YearAggregate
35- import no.java.conf.model.search.hasFilter
36- import no.java.conf.model.search.hasQuery
3713import no.java.conf.model.sessions.Session
3814import no.java.conf.service.search.ElasticIndexer
3915import no.java.conf.service.search.ElasticIngester
16+ import no.java.conf.service.search.ElasticSearcher
4017import kotlin.time.measureTimedValue
4118
4219private const val INDEX_NAME = " javazone"
@@ -50,9 +27,9 @@ enum class State {
5027}
5128
5229class SearchService (
53- private val client : SearchClient ,
5430 private val indexer : ElasticIndexer ,
5531 private val ingester : ElasticIngester ,
32+ private val searcher : ElasticSearcher ,
5633 private val skipIndex : Boolean ,
5734) {
5835 private var readyState = State .NEW
@@ -105,15 +82,7 @@ class SearchService(
10582 suspend fun allVideos (): List <VideoSearchResponse > {
10683 ensureReady(readyState)
10784
108- val docCount = client.totalDocs()
109-
110- val sessions =
111- client.search(INDEX_NAME ) {
112- resultSize = docCount.toInt()
113- query = exists(" video" )
114- }
115-
116- return sessions.parseHits<VideoSearchResponse >().sortedBy { - it.year }
85+ return searcher.allVideos(INDEX_NAME )
11786 }
11887
11988 fun state (): State = readyState
@@ -126,27 +95,7 @@ class SearchService(
12695
12796 ensureReady(readyState)
12897
129- val docCount = client.totalDocs()
130-
131- val searchResult =
132- client.search(INDEX_NAME ) {
133- addQuery(docCount, searchRequest)
134-
135- addLanguageAggregate(docCount)
136- addFormatAggregate(docCount)
137- addYearAggregate(docCount)
138-
139- logger.debug { this .json() }
140- }
141-
142- ensure(searchResult.aggregations != null ) {
143- raise(AggregationsNotFound )
144- }
145-
146- return SearchResponse (
147- searchResult.parseHits<SessionResponse >().sortedBy { - it.year },
148- searchResult.aggregations!! .buildResponse()
149- )
98+ return searcher.textSearch(INDEX_NAME , searchRequest)
15099 }
151100}
152101
@@ -155,119 +104,3 @@ private fun Raise<ApiError>.ensureReady(readyState: State) {
155104 raise(IndexNotReady )
156105 }
157106}
158-
159- private fun Aggregations.buildResponse () =
160- AggregateResponse (
161- languages =
162- this
163- .termsResult(" by-language" )
164- .parsedBuckets
165- .map { LanguageAggregate (it.parsed.key, it.parsed.docCount) },
166- formats =
167- this
168- .termsResult(" by-format" )
169- .parsedBuckets
170- .map { FormatAggregate (it.parsed.key, it.parsed.docCount) },
171- years =
172- this
173- .termsResult(" by-year" )
174- .parsedBuckets
175- .map { YearAggregate (it.parsed.key.toInt(), it.parsed.docCount) }
176- .sortedBy { - it.year },
177- )
178-
179- private fun SearchDSL.addLanguageAggregate (docCount : Long ) {
180- this .agg(
181- " by-language" ,
182- TermsAgg (Session ::language.name) {
183- aggSize = docCount
184- minDocCount = 1
185- }
186- )
187- }
188-
189- private fun SearchDSL.addFormatAggregate (docCount : Long ) {
190- this .agg(
191- " by-format" ,
192- TermsAgg (Session ::format.name) {
193- aggSize = docCount
194- minDocCount = 1
195- }
196- )
197- }
198-
199- private fun SearchDSL.addYearAggregate (docCount : Long ) {
200- this .agg(
201- " by-year" ,
202- TermsAgg (Session ::year) {
203- aggSize = docCount
204- minDocCount = 1
205- }
206- )
207- }
208-
209- private fun SearchDSL.addQuery (
210- docCount : Long ,
211- searchRequest : TextSearchRequest
212- ) {
213- logger.debug { " Building query for $searchRequest " }
214-
215- resultSize =
216- when (! searchRequest.hasQuery() && ! searchRequest.hasFilter()) {
217- true -> 0
218- false -> docCount.toInt()
219- }
220-
221- val queryString =
222- when {
223- searchRequest.hasQuery() -> searchRequest.query
224- searchRequest.hasFilter() -> " *"
225- else -> null
226- }
227-
228- val textQuery =
229- queryString?.let { q ->
230- bool {
231- should(
232- simpleQueryString(q, " title" , " abstract" , " intendedAudience" ),
233- nested {
234- path = " speakers"
235- query = simpleQueryString(q, " speakers.name" , " speakers.bio" )
236- }
237- )
238- }
239- }
240-
241- val yearQuery =
242- searchRequest.years.ifEmpty { null }?.let { years ->
243- terms(
244- field = " year" ,
245- values = years.map { it.toString() }.toTypedArray()
246- )
247- }
248-
249- val languageQuery =
250- searchRequest.languages.ifEmpty { null }?.let { languages ->
251- terms(
252- field = " language" ,
253- values = languages.toTypedArray()
254- )
255- }
256-
257- val formatQuery =
258- searchRequest.formats.ifEmpty { null }?.let { formats ->
259- terms(
260- field = " format" ,
261- values = formats.toTypedArray()
262- )
263- }
264-
265- this .query =
266- bool {
267- must(
268- listOfNotNull(textQuery, yearQuery, languageQuery, formatQuery)
269- )
270- }
271- }
272-
273- private suspend fun SearchClient.totalDocs () = this .count(INDEX_NAME ).count
0 commit comments