Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to access search response fields #185

Merged
merged 3 commits into from
Apr 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import zio.elasticsearch._
import zio.elasticsearch.executor.response.{
CountResponse,
CreateResponse,
DocumentWithHighlightsAndSort,
GetResponse,
SearchWithAggregationsResponse,
UpdateByQueryResponse
Expand Down Expand Up @@ -318,7 +319,7 @@ private[elasticsearch] final class HttpExecutor private (esConfig: ElasticConfig
.response(asJson[GetResponse])
).flatMap { response =>
response.code match {
case HttpOk => ZIO.attempt(new GetResult(doc = response.body.toOption.map(r => result.Item(r.source))))
case HttpOk => ZIO.attempt(new GetResult(doc = response.body.toOption.map(r => Item(r.source))))
case HttpNotFound => ZIO.succeed(new GetResult(doc = None))
case _ => ZIO.fail(handleFailuresFromCustomResponse(response))
}
Expand All @@ -338,13 +339,13 @@ private[elasticsearch] final class HttpExecutor private (esConfig: ElasticConfig
response.body.fold(
e => ZIO.fail(new ElasticException(s"Exception occurred: ${e.getMessage}")),
value =>
value.resultsWithHighlights match {
value.resultsWithHighlightsAndSort match {
case Nil =>
ZIO.succeed((Chunk.empty, None))
case _ =>
ZIO.succeed(
(
itemFromResultsWithHighlights(value.resultsWithHighlights),
itemsFromDocumentsWithHighlights(value.resultsWithHighlightsAndSort),
value.scrollId.orElse(Some(scrollId))
)
)
Expand Down Expand Up @@ -372,8 +373,11 @@ private[elasticsearch] final class HttpExecutor private (esConfig: ElasticConfig
.fromEither(value.innerHitsResults)
.map { innerHitsResults =>
new SearchResult(
itemFromResultsWithHighlightsAndInnerHits(value.resultsWithHighlights, innerHitsResults).toList,
value.lastSortField
itemsFromDocumentsWithHighlightsSortAndInnerHits(
value.resultsWithHighlightsAndSort,
innerHitsResults
).toList,
value
)
}
.mapError(error => DecodingException(s"Could not parse inner_hits: $error"))
Expand Down Expand Up @@ -415,7 +419,7 @@ private[elasticsearch] final class HttpExecutor private (esConfig: ElasticConfig
response.body.fold(
e => ZIO.fail(new ElasticException(s"Exception occurred: ${e.getMessage}")),
body => {
body.resultsWithHighlights match {
body.resultsWithHighlightsAndSort match {
case Nil => ZIO.succeed((Chunk.empty, None))
case _ =>
body.pitId match {
Expand All @@ -424,7 +428,7 @@ private[elasticsearch] final class HttpExecutor private (esConfig: ElasticConfig
case Some(newSearchAfter) =>
ZIO.succeed(
(
itemFromResultsWithHighlights(body.resultsWithHighlights),
itemsFromDocumentsWithHighlights(body.resultsWithHighlightsAndSort),
Some((newPitId, Some(newSearchAfter)))
)
)
Expand Down Expand Up @@ -470,11 +474,9 @@ private[elasticsearch] final class HttpExecutor private (esConfig: ElasticConfig
value =>
ZIO.succeed(
new SearchAndAggregateResult(
value.resultsWithHighlights.map { case (source, highlight) =>
Item(source, highlight)
},
itemsFromDocumentsWithHighlights(value.resultsWithHighlightsAndSort).toList,
value.aggs,
value.lastSortField
value
)
)
)
Expand All @@ -501,7 +503,7 @@ private[elasticsearch] final class HttpExecutor private (esConfig: ElasticConfig
e => ZIO.fail(new ElasticException(s"Exception occurred: ${e.getMessage}")),
value =>
ZIO.succeed(
(itemFromResultsWithHighlights(value.resultsWithHighlights), value.scrollId)
(itemsFromDocumentsWithHighlights(value.resultsWithHighlightsAndSort), value.scrollId)
)
)
case _ =>
Expand Down Expand Up @@ -580,17 +582,15 @@ private[elasticsearch] final class HttpExecutor private (esConfig: ElasticConfig
)
}

private def itemFromResultsWithHighlights(results: List[(Json, Option[Json])]): Chunk[Item] =
Chunk.fromIterable(results).map { case (source, highlight) =>
Item(source, highlight)
}
private def itemsFromDocumentsWithHighlights(results: List[DocumentWithHighlightsAndSort]): Chunk[Item] =
Chunk.fromIterable(results).map(r => Item(raw = r.source, highlight = r.highlight, sort = r.sort))

private def itemFromResultsWithHighlightsAndInnerHits(
results: List[(Json, Option[Json])],
private def itemsFromDocumentsWithHighlightsSortAndInnerHits(
results: List[DocumentWithHighlightsAndSort],
innerHits: List[Map[String, List[Json]]]
): Chunk[Item] =
Chunk.fromIterable(results).zip(innerHits).map { case ((source, highlight), innerHits) =>
Item(source, highlight, innerHits)
Chunk.fromIterable(results).zip(innerHits).map { case (r, innerHits) =>
Item(raw = r.source, highlight = r.highlight, innerHits = innerHits, sort = r.sort)
}

private def sendRequest(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,8 @@ private[elasticsearch] final case class SearchWithAggregationsResponse(
)
.toEitherWith(_.mkString(", "))

lazy val results: List[Json] = hits.hits.map(_.source)

lazy val resultsWithHighlights: List[(Json, Option[Json])] = hits.hits.map(h => (h.source, h.highlight))
lazy val resultsWithHighlightsAndSort: List[DocumentWithHighlightsAndSort] =
hits.hits.map(h => DocumentWithHighlightsAndSort(h.source, h.highlight, h.sort))

lazy val lastSortField: Option[Json] = hits.hits.lastOption.flatMap(_.sort)

Expand Down Expand Up @@ -90,3 +89,9 @@ private[elasticsearch] object SearchWithAggregationsResponse {
implicit val decoder: JsonDecoder[SearchWithAggregationsResponse] =
DeriveJsonDecoder.gen[SearchWithAggregationsResponse]
}

private[elasticsearch] case class DocumentWithHighlightsAndSort(
source: Json,
highlight: Option[Json],
sort: Option[Json]
)
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

package zio.elasticsearch.result

import zio.elasticsearch.executor.response.AggregationResponse
import zio.elasticsearch.executor.response.{AggregationResponse, SearchWithAggregationsResponse}
import zio.json.ast.Json
import zio.prelude.ZValidation
import zio.schema.Schema
Expand Down Expand Up @@ -59,7 +59,7 @@ final class GetResult private[elasticsearch] (private val doc: Option[Item]) ext

final class SearchResult private[elasticsearch] (
private val hits: List[Item],
private val lastSort: Option[Json]
private val fullResponse: SearchWithAggregationsResponse
) extends DocumentResult[List] {
def documentAs[A: Schema]: IO[DecodingException, List[A]] =
ZIO.fromEither {
Expand All @@ -70,13 +70,17 @@ final class SearchResult private[elasticsearch] (

lazy val items: UIO[List[Item]] = ZIO.succeed(hits)

lazy val lastSortValue: UIO[Option[Json]] = ZIO.succeed(lastSort)
lazy val lastSortValue: UIO[Option[Json]] = ZIO.succeed(fullResponse.lastSortField)

lazy val response: UIO[SearchWithAggregationsResponse] = ZIO.succeed(fullResponse)

lazy val total: UIO[Long] = ZIO.succeed(fullResponse.hits.total.value)
}

final class SearchAndAggregateResult private[elasticsearch] (
private val hits: List[Item],
private val aggs: Map[String, AggregationResponse],
private val lastSort: Option[Json]
private val fullResponse: SearchWithAggregationsResponse
) extends DocumentResult[List]
with AggregationsResult {
def aggregation(name: String): Task[Option[AggregationResponse]] =
Expand All @@ -96,5 +100,9 @@ final class SearchAndAggregateResult private[elasticsearch] (

lazy val items: UIO[List[Item]] = ZIO.succeed(hits)

lazy val lastSortValue: UIO[Option[Json]] = ZIO.succeed(lastSort)
lazy val lastSortValue: UIO[Option[Json]] = ZIO.succeed(fullResponse.lastSortField)

lazy val response: UIO[SearchWithAggregationsResponse] = ZIO.succeed(fullResponse)

lazy val total: UIO[Long] = ZIO.succeed(fullResponse.hits.total.value)
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ import zio.schema.codec.JsonCodec.JsonDecoder
final case class Item(
raw: Json,
private val highlight: Option[Json] = None,
private val innerHits: Map[String, List[Json]] = Map.empty
private val innerHits: Map[String, List[Json]] = Map.empty,
sort: Option[Json] = None
) {
def documentAs[A](implicit schema: Schema[A]): Either[DecodeError, A] = JsonDecoder.decode(schema, raw.toString)

Expand Down