From 28fea6f0ade99cef61410cd7095b23528d33a6b6 Mon Sep 17 00:00:00 2001 From: Dimitrije Bulaja Date: Fri, 19 May 2023 15:36:05 +0200 Subject: [PATCH 1/7] Add highlights and source to InnerHits --- .../zio/elasticsearch/query/InnerHits.scala | 60 ++++- .../zio/elasticsearch/ElasticQuerySpec.scala | 52 +++- .../zio/elasticsearch/InnerHitsSpec.scala | 237 ++++++++++++++++++ 3 files changed, 340 insertions(+), 9 deletions(-) create mode 100644 modules/library/src/test/scala/zio/elasticsearch/InnerHitsSpec.scala diff --git a/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala b/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala index be59f2217..fd41a45ed 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala @@ -17,29 +17,81 @@ package zio.elasticsearch.query import zio.Chunk +import zio.elasticsearch.ElasticPrimitive.ElasticPrimitiveOps +import zio.elasticsearch.highlights.Highlights import zio.json.ast.Json -import zio.json.ast.Json.{Num, Obj, Str} +import zio.json.ast.Json.{Arr, Num, Obj, Str} final case class InnerHits private[elasticsearch] ( + private val excluded: Option[Chunk[String]], private val from: Option[Int], + private val highlights: Option[Highlights], + private val included: Option[Chunk[String]], private val name: Option[String], private val size: Option[Int] ) { self => + + /** + * Specifies one or more fields to be excluded in the response of a [[zio.elasticsearch.query.InnerHits]]. + * + * @param field + * a field to be excluded + * @param fields + * fields to be excluded + * @return + * an instance of a [[zio.elasticsearch.query.InnerHits]] with specified fields to be excluded. + */ + def excludes(field: String, fields: String*): InnerHits = + self.copy(excluded = excluded.map(_ ++ (field +: fields)).orElse(Some(field +: Chunk.fromIterable(fields)))) + def from(value: Int): InnerHits = self.copy(from = Some(value)) + def highlights(value: Highlights): InnerHits = + self.copy(highlights = Some(value)) + + /** + * Specifies one or more fields to be included in the response of a [[zio.elasticsearch.query.InnerHits]]. + * + * @param field + * a field to be included + * @param fields + * fields to be included + * @return + * an instance of a [[zio.elasticsearch.query.InnerHits]] with specified fields to be included. + */ + def includes(field: String, fields: String*): InnerHits = + self.copy(included = included.map(_ ++ (field +: fields)).orElse(Some(field +: Chunk.fromIterable(fields)))) + def name(value: String): InnerHits = self.copy(name = Some(value)) def size(value: Int): InnerHits = self.copy(size = Some(value)) - def toStringJsonPair: (String, Json) = + private[elasticsearch] def toStringJsonPair: (String, Json) = { + val sourceJson: Option[Json] = + (included, excluded) match { + case (None, None) => None + case (included, excluded) => + val includes = included.fold(Obj())(included => Obj("includes" -> Arr(included.map(_.toJson)))) + val excludes = excluded.fold(Obj())(excluded => Obj("excludes" -> Arr(excluded.map(_.toJson)))) + Some(includes merge excludes) + } + "inner_hits" -> Obj( - Chunk(from.map("from" -> Num(_)), size.map("size" -> Num(_)), name.map("name" -> Str(_))).flatten + Chunk( + from.map("from" -> Num(_)), + size.map("size" -> Num(_)), + name.map("name" -> Str(_)), + highlights.map("highlight" -> _.toJson), + sourceJson.map("_source" -> _) + ).flatten ) + } } object InnerHits { - def apply(): InnerHits = InnerHits(from = None, name = None, size = None) + def apply(): InnerHits = + InnerHits(excluded = None, from = None, highlights = None, included = None, name = None, size = None) } diff --git a/modules/library/src/test/scala/zio/elasticsearch/ElasticQuerySpec.scala b/modules/library/src/test/scala/zio/elasticsearch/ElasticQuerySpec.scala index 2994c96c4..6bd044c4b 100644 --- a/modules/library/src/test/scala/zio/elasticsearch/ElasticQuerySpec.scala +++ b/modules/library/src/test/scala/zio/elasticsearch/ElasticQuerySpec.scala @@ -17,6 +17,7 @@ package zio.elasticsearch import zio.Chunk +import zio.elasticsearch.ElasticHighlight.highlight import zio.elasticsearch.ElasticQuery._ import zio.elasticsearch.domain._ import zio.elasticsearch.query.DistanceType.Plane @@ -761,7 +762,16 @@ object ElasticQuerySpec extends ZIOSpecDefault { query = MatchAll(boost = None), scoreMode = None, ignoreUnmapped = None, - innerHitsField = Some(InnerHits(from = Some(0), name = Some("innerHitName"), size = Some(3))) + innerHitsField = Some( + InnerHits( + excluded = None, + from = Some(0), + highlights = None, + included = None, + name = Some("innerHitName"), + size = Some(3) + ) + ) ) ) ) && @@ -772,7 +782,9 @@ object ElasticQuerySpec extends ZIOSpecDefault { query = MatchAll(boost = None), scoreMode = None, ignoreUnmapped = None, - innerHitsField = Some(InnerHits(None, None, None)) + innerHitsField = Some( + InnerHits(excluded = None, from = None, highlights = None, included = None, name = None, size = None) + ) ) ) ) && @@ -794,7 +806,16 @@ object ElasticQuerySpec extends ZIOSpecDefault { query = MatchAll(boost = None), scoreMode = Some(ScoreMode.Max), ignoreUnmapped = Some(false), - innerHitsField = Some(InnerHits(None, Some("innerHitName"), None)) + innerHitsField = Some( + InnerHits( + excluded = None, + from = None, + highlights = None, + included = None, + name = Some("innerHitName"), + size = None + ) + ) ) ) ) @@ -2027,7 +2048,15 @@ object ElasticQuerySpec extends ZIOSpecDefault { val queryWithNested = nested(TestDocument.subDocumentList, nested("items", term("testField", "test"))) val queryWithIgnoreUnmapped = nested(TestDocument.subDocumentList, matchAll).ignoreUnmappedTrue val queryWithInnerHits = - nested(TestDocument.subDocumentList, matchAll).innerHits(InnerHits().from(0).size(3).name("innerHitName")) + nested(TestDocument.subDocumentList, matchAll).innerHits( + InnerHits() + .from(0) + .size(3) + .name("innerHitName") + .highlights(highlight("stringField")) + .excludes("longField") + .includes("intField") + ) val queryWithInnerHitsEmpty = nested(TestDocument.subDocumentList, matchAll).innerHits val queryWithScoreMode = nested(TestDocument.subDocumentList, matchAll).scoreMode(ScoreMode.Avg) val queryWithAllParams = nested(TestDocument.subDocumentList, matchAll).ignoreUnmappedFalse @@ -2091,7 +2120,20 @@ object ElasticQuerySpec extends ZIOSpecDefault { | "inner_hits": { | "from": 0, | "size": 3, - | "name": "innerHitName" + | "name": "innerHitName", + | "highlight" : { + | "fields" : { + | "stringField" : {} + | } + | }, + | "_source" : { + | "includes" : [ + | "intField" + | ], + | "excludes" : [ + | "longField" + | ] + | } | } | } |} diff --git a/modules/library/src/test/scala/zio/elasticsearch/InnerHitsSpec.scala b/modules/library/src/test/scala/zio/elasticsearch/InnerHitsSpec.scala new file mode 100644 index 000000000..5dbcd88ca --- /dev/null +++ b/modules/library/src/test/scala/zio/elasticsearch/InnerHitsSpec.scala @@ -0,0 +1,237 @@ +package zio.elasticsearch + +import zio.Chunk +import zio.elasticsearch.ElasticHighlight.highlight +import zio.elasticsearch.highlights.{HighlightField, Highlights} +import zio.elasticsearch.query.InnerHits +import zio.elasticsearch.utils.RichString +import zio.json.ast.Json.Obj +import zio.test.Assertion.equalTo +import zio.test.{Spec, TestEnvironment, ZIOSpecDefault, assert} + +object InnerHitsSpec extends ZIOSpecDefault { + + def spec: Spec[TestEnvironment, Any] = + suite("InnerHits")( + test("constructing") { + val innerHits = InnerHits.apply() + val innerHitsWithExcluded = InnerHits.apply().excludes("longField") + val innerHitsWithFrom = InnerHits.apply().from(2) + val innerHitsWithHighlights = InnerHits.apply().highlights(highlight("stringField")) + val innerHitsWithIncluded = InnerHits.apply().includes("intField") + val innerHitsWithName = InnerHits.apply().name("innerHitName") + val innerHitsWithSize = InnerHits.apply().size(5) + val innerHitsWithAllParams = + InnerHits + .apply() + .excludes("longField") + .from(2) + .highlights(highlight("stringField")) + .includes("intField") + .name("innerHitName") + .size(5) + + assert(innerHits)( + equalTo( + InnerHits(excluded = None, from = None, highlights = None, included = None, name = None, size = None) + ) + ) && assert(innerHitsWithExcluded)( + equalTo( + InnerHits( + excluded = Some(Chunk("longField")), + from = None, + highlights = None, + included = None, + name = None, + size = None + ) + ) + ) && assert(innerHitsWithFrom)( + equalTo( + InnerHits( + excluded = None, + from = Some(2), + highlights = None, + included = None, + name = None, + size = None + ) + ) + ) && assert(innerHitsWithHighlights)( + equalTo( + InnerHits( + excluded = None, + from = None, + highlights = Some(Highlights(fields = Chunk(HighlightField("stringField")), config = Map.empty)), + included = None, + name = None, + size = None + ) + ) + ) && assert(innerHitsWithIncluded)( + equalTo( + InnerHits( + excluded = None, + from = None, + highlights = None, + included = Some(Chunk("intField")), + name = None, + size = None + ) + ) + ) && assert(innerHitsWithName)( + equalTo( + InnerHits( + excluded = None, + from = None, + highlights = None, + included = None, + name = Some("innerHitName"), + size = None + ) + ) + ) && assert(innerHitsWithSize)( + equalTo( + InnerHits(excluded = None, from = None, highlights = None, included = None, name = None, size = Some(5)) + ) + ) && assert(innerHitsWithAllParams)( + equalTo( + InnerHits( + excluded = Some(Chunk("longField")), + from = Some(2), + highlights = Some(Highlights(fields = Chunk(HighlightField("stringField")), config = Map.empty)), + included = Some(Chunk("intField")), + name = Some("innerHitName"), + size = Some(5) + ) + ) + ) + }, + test("encoding as JSON") { + val innerHits = InnerHits.apply() + val innerHitsWithExcluded = InnerHits.apply().excludes("longField") + val innerHitsWithFrom = InnerHits.apply().from(2) + val innerHitsWithHighlights = InnerHits.apply().highlights(highlight("stringField")) + val innerHitsWithIncluded = InnerHits.apply().includes("intField") + val innerHitsWithName = InnerHits.apply().name("innerHitName") + val innerHitsWithSize = InnerHits.apply().size(5) + val innerHitsWithAllParams = + InnerHits + .apply() + .excludes("longField") + .from(2) + .highlights(highlight("stringField")) + .includes("intField") + .name("innerHitName") + .size(5) + + val expected = + """ + |{ + | "inner_hits": { + | + | } + |} + |""".stripMargin + + val expectedWithExcluded = + """ + |{ + | "inner_hits": { + | "_source" : { + | "excludes" : [ + | "longField" + | ] + | } + | } + |} + |""".stripMargin + + val expectedWithFrom = + """ + |{ + | "inner_hits": { + | "from": 2 + | } + |} + |""".stripMargin + + val expectedWithHighlights = + """ + |{ + | "inner_hits": { + | "highlight" : { + | "fields" : { + | "stringField" : {} + | } + | } + | } + |} + |""".stripMargin + + val expectedWithIncluded = + """ + |{ + | "inner_hits": { + | "_source" : { + | "includes" : [ + | "intField" + | ] + | } + | } + |} + |""".stripMargin + + val expectedWithName = + """ + |{ + | "inner_hits": { + | "name": "innerHitName" + | } + |} + |""".stripMargin + + val expectedWithSize = + """ + |{ + | "inner_hits": { + | "size": 5 + | } + |} + |""".stripMargin + + val expectedWithAllParams = + """ + |{ + | "inner_hits": { + | "from": 2, + | "size": 5, + | "name": "innerHitName", + | "highlight" : { + | "fields" : { + | "stringField" : {} + | } + | }, + | "_source" : { + | "includes" : [ + | "intField" + | ], + | "excludes" : [ + | "longField" + | ] + | } + | } + |} + |""".stripMargin + + assert(Obj(innerHits.toStringJsonPair))(equalTo(expected.toJson)) && + assert(Obj(innerHitsWithExcluded.toStringJsonPair))(equalTo(expectedWithExcluded.toJson)) && + assert(Obj(innerHitsWithFrom.toStringJsonPair))(equalTo(expectedWithFrom.toJson)) && + assert(Obj(innerHitsWithHighlights.toStringJsonPair))(equalTo(expectedWithHighlights.toJson)) && + assert(Obj(innerHitsWithIncluded.toStringJsonPair))(equalTo(expectedWithIncluded.toJson)) && + assert(Obj(innerHitsWithName.toStringJsonPair))(equalTo(expectedWithName.toJson)) && + assert(Obj(innerHitsWithSize.toStringJsonPair))(equalTo(expectedWithSize.toJson)) && + assert(Obj(innerHitsWithAllParams.toStringJsonPair))(equalTo(expectedWithAllParams.toJson)) + } + ) +} From aa1b4090c85b09631b7fbdee20aa70c00fd23c01 Mon Sep 17 00:00:00 2001 From: Dimitrije Bulaja Date: Fri, 19 May 2023 15:37:04 +0200 Subject: [PATCH 2/7] Add scaladoc for InnerHits methods --- .../zio/elasticsearch/query/InnerHits.scala | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala b/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala index fd41a45ed..9cb4e9b0d 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala @@ -44,9 +44,25 @@ final case class InnerHits private[elasticsearch] ( def excludes(field: String, fields: String*): InnerHits = self.copy(excluded = excluded.map(_ ++ (field +: fields)).orElse(Some(field +: Chunk.fromIterable(fields)))) + /** + * Specifies the starting offset of the [[zio.elasticsearch.query.InnerHits]] to be returned. + * + * @param value + * the starting offset value + * @return + * an instance of a [[zio.elasticsearch.query.InnerHits]] with the specified starting offset. + */ def from(value: Int): InnerHits = self.copy(from = Some(value)) + /** + * Specifies the highlighting configuration for the [[zio.elasticsearch.query.InnerHits]]. + * + * @param value + * the [[zio.elasticsearch.highlights.Highlights]] configuration + * @return + * an instance of a [[zio.elasticsearch.query.InnerHits]] with the specified highlighting configuration. + */ def highlights(value: Highlights): InnerHits = self.copy(highlights = Some(value)) @@ -63,9 +79,25 @@ final case class InnerHits private[elasticsearch] ( def includes(field: String, fields: String*): InnerHits = self.copy(included = included.map(_ ++ (field +: fields)).orElse(Some(field +: Chunk.fromIterable(fields)))) + /** + * Specifies the name of the [[zio.elasticsearch.query.InnerHits]]. + * + * @param value + * the name of the [[zio.elasticsearch.query.InnerHits]] + * @return + * an instance of a [[zio.elasticsearch.query.InnerHits]] with the specified name. + */ def name(value: String): InnerHits = self.copy(name = Some(value)) + /** + * Specifies the maximum number of [[zio.elasticsearch.query.InnerHits]] to be returned. + * + * @param value + * the maximum number of [[zio.elasticsearch.query.InnerHits]] + * @return + * an instance of a [[zio.elasticsearch.query.InnerHits]] with the specified size. + */ def size(value: Int): InnerHits = self.copy(size = Some(value)) From 182f6f5db961825eaff51e385b32350ddb58dc09 Mon Sep 17 00:00:00 2001 From: Dimitrije Bulaja Date: Mon, 22 May 2023 15:11:03 +0200 Subject: [PATCH 3/7] Refactor inner hits --- .../elasticsearch/executor/HttpExecutor.scala | 2 + .../zio/elasticsearch/query/InnerHits.scala | 17 +++-- .../zio/elasticsearch/ElasticQuerySpec.scala | 17 +++-- .../zio/elasticsearch/InnerHitsSpec.scala | 73 ++++++++++--------- 4 files changed, 62 insertions(+), 47 deletions(-) diff --git a/modules/library/src/main/scala/zio/elasticsearch/executor/HttpExecutor.scala b/modules/library/src/main/scala/zio/elasticsearch/executor/HttpExecutor.scala index 0c3f6cd3b..9f7be9163 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/executor/HttpExecutor.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/executor/HttpExecutor.scala @@ -375,6 +375,8 @@ private[elasticsearch] final class HttpExecutor private (esConfig: ElasticConfig ).flatMap { response => response.code match { case HttpOk => + println(r.toJson) + println(response.body) response.body.fold( e => ZIO.fail(new ElasticException(s"Exception occurred: ${e.getMessage}")), value => diff --git a/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala b/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala index 9cb4e9b0d..7e8b7a268 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala @@ -23,10 +23,10 @@ import zio.json.ast.Json import zio.json.ast.Json.{Arr, Num, Obj, Str} final case class InnerHits private[elasticsearch] ( - private val excluded: Option[Chunk[String]], + private val excluded: Chunk[String], + private val included: Chunk[String], private val from: Option[Int], private val highlights: Option[Highlights], - private val included: Option[Chunk[String]], private val name: Option[String], private val size: Option[Int] ) { self => @@ -42,7 +42,7 @@ final case class InnerHits private[elasticsearch] ( * an instance of a [[zio.elasticsearch.query.InnerHits]] with specified fields to be excluded. */ def excludes(field: String, fields: String*): InnerHits = - self.copy(excluded = excluded.map(_ ++ (field +: fields)).orElse(Some(field +: Chunk.fromIterable(fields)))) + self.copy(excluded = excluded ++ (field +: fields)) /** * Specifies the starting offset of the [[zio.elasticsearch.query.InnerHits]] to be returned. @@ -77,7 +77,7 @@ final case class InnerHits private[elasticsearch] ( * an instance of a [[zio.elasticsearch.query.InnerHits]] with specified fields to be included. */ def includes(field: String, fields: String*): InnerHits = - self.copy(included = included.map(_ ++ (field +: fields)).orElse(Some(field +: Chunk.fromIterable(fields)))) + self.copy(included = included ++ (field +: fields)) /** * Specifies the name of the [[zio.elasticsearch.query.InnerHits]]. @@ -104,10 +104,11 @@ final case class InnerHits private[elasticsearch] ( private[elasticsearch] def toStringJsonPair: (String, Json) = { val sourceJson: Option[Json] = (included, excluded) match { - case (None, None) => None + case (included, excluded) if included.isEmpty && excluded.isEmpty => + None case (included, excluded) => - val includes = included.fold(Obj())(included => Obj("includes" -> Arr(included.map(_.toJson)))) - val excludes = excluded.fold(Obj())(excluded => Obj("excludes" -> Arr(excluded.map(_.toJson)))) + val includes = if (included.isEmpty) Obj() else Obj("includes" -> Arr(included.map(_.toJson))) + val excludes = if (excluded.isEmpty) Obj() else Obj("excludes" -> Arr(excluded.map(_.toJson))) Some(includes merge excludes) } @@ -125,5 +126,5 @@ final case class InnerHits private[elasticsearch] ( object InnerHits { def apply(): InnerHits = - InnerHits(excluded = None, from = None, highlights = None, included = None, name = None, size = None) + InnerHits(excluded = Chunk(), included = Chunk(), from = None, highlights = None, name = None, size = None) } diff --git a/modules/library/src/test/scala/zio/elasticsearch/ElasticQuerySpec.scala b/modules/library/src/test/scala/zio/elasticsearch/ElasticQuerySpec.scala index 6bd044c4b..fb6d22f76 100644 --- a/modules/library/src/test/scala/zio/elasticsearch/ElasticQuerySpec.scala +++ b/modules/library/src/test/scala/zio/elasticsearch/ElasticQuerySpec.scala @@ -764,10 +764,10 @@ object ElasticQuerySpec extends ZIOSpecDefault { ignoreUnmapped = None, innerHitsField = Some( InnerHits( - excluded = None, + excluded = Chunk(), + included = Chunk(), from = Some(0), highlights = None, - included = None, name = Some("innerHitName"), size = Some(3) ) @@ -783,7 +783,14 @@ object ElasticQuerySpec extends ZIOSpecDefault { scoreMode = None, ignoreUnmapped = None, innerHitsField = Some( - InnerHits(excluded = None, from = None, highlights = None, included = None, name = None, size = None) + InnerHits( + excluded = Chunk(), + included = Chunk(), + from = None, + highlights = None, + name = None, + size = None + ) ) ) ) @@ -808,10 +815,10 @@ object ElasticQuerySpec extends ZIOSpecDefault { ignoreUnmapped = Some(false), innerHitsField = Some( InnerHits( - excluded = None, + excluded = Chunk(), + included = Chunk(), from = None, highlights = None, - included = None, name = Some("innerHitName"), size = None ) diff --git a/modules/library/src/test/scala/zio/elasticsearch/InnerHitsSpec.scala b/modules/library/src/test/scala/zio/elasticsearch/InnerHitsSpec.scala index 5dbcd88ca..aece631e2 100644 --- a/modules/library/src/test/scala/zio/elasticsearch/InnerHitsSpec.scala +++ b/modules/library/src/test/scala/zio/elasticsearch/InnerHitsSpec.scala @@ -14,34 +14,33 @@ object InnerHitsSpec extends ZIOSpecDefault { def spec: Spec[TestEnvironment, Any] = suite("InnerHits")( test("constructing") { - val innerHits = InnerHits.apply() - val innerHitsWithExcluded = InnerHits.apply().excludes("longField") - val innerHitsWithFrom = InnerHits.apply().from(2) - val innerHitsWithHighlights = InnerHits.apply().highlights(highlight("stringField")) - val innerHitsWithIncluded = InnerHits.apply().includes("intField") - val innerHitsWithName = InnerHits.apply().name("innerHitName") - val innerHitsWithSize = InnerHits.apply().size(5) + val innerHits = InnerHits() + val innerHitsWithExcluded = InnerHits().excludes("longField") + val innerHitsWithFrom = InnerHits().from(2) + val innerHitsWithHighlights = InnerHits().highlights(highlight("stringField")) + val innerHitsWithIncluded = InnerHits().includes("intField") + val innerHitsWithName = InnerHits().name("innerHitName") + val innerHitsWithSize = InnerHits().size(5) val innerHitsWithAllParams = - InnerHits - .apply() + InnerHits() .excludes("longField") + .includes("intField") .from(2) .highlights(highlight("stringField")) - .includes("intField") .name("innerHitName") .size(5) assert(innerHits)( equalTo( - InnerHits(excluded = None, from = None, highlights = None, included = None, name = None, size = None) + InnerHits(excluded = Chunk(), from = None, highlights = None, included = Chunk(), name = None, size = None) ) ) && assert(innerHitsWithExcluded)( equalTo( InnerHits( - excluded = Some(Chunk("longField")), + excluded = Chunk("longField"), + included = Chunk(), from = None, highlights = None, - included = None, name = None, size = None ) @@ -49,10 +48,10 @@ object InnerHitsSpec extends ZIOSpecDefault { ) && assert(innerHitsWithFrom)( equalTo( InnerHits( - excluded = None, + excluded = Chunk(), + included = Chunk(), from = Some(2), highlights = None, - included = None, name = None, size = None ) @@ -60,10 +59,10 @@ object InnerHitsSpec extends ZIOSpecDefault { ) && assert(innerHitsWithHighlights)( equalTo( InnerHits( - excluded = None, + excluded = Chunk(), + included = Chunk(), from = None, highlights = Some(Highlights(fields = Chunk(HighlightField("stringField")), config = Map.empty)), - included = None, name = None, size = None ) @@ -71,10 +70,10 @@ object InnerHitsSpec extends ZIOSpecDefault { ) && assert(innerHitsWithIncluded)( equalTo( InnerHits( - excluded = None, + excluded = Chunk(), + included = Chunk("intField"), from = None, highlights = None, - included = Some(Chunk("intField")), name = None, size = None ) @@ -82,25 +81,32 @@ object InnerHitsSpec extends ZIOSpecDefault { ) && assert(innerHitsWithName)( equalTo( InnerHits( - excluded = None, + excluded = Chunk(), + included = Chunk(), from = None, highlights = None, - included = None, name = Some("innerHitName"), size = None ) ) ) && assert(innerHitsWithSize)( equalTo( - InnerHits(excluded = None, from = None, highlights = None, included = None, name = None, size = Some(5)) + InnerHits( + excluded = Chunk(), + included = Chunk(), + from = None, + highlights = None, + name = None, + size = Some(5) + ) ) ) && assert(innerHitsWithAllParams)( equalTo( InnerHits( - excluded = Some(Chunk("longField")), + excluded = Chunk("longField"), + included = Chunk("intField"), from = Some(2), highlights = Some(Highlights(fields = Chunk(HighlightField("stringField")), config = Map.empty)), - included = Some(Chunk("intField")), name = Some("innerHitName"), size = Some(5) ) @@ -108,20 +114,19 @@ object InnerHitsSpec extends ZIOSpecDefault { ) }, test("encoding as JSON") { - val innerHits = InnerHits.apply() - val innerHitsWithExcluded = InnerHits.apply().excludes("longField") - val innerHitsWithFrom = InnerHits.apply().from(2) - val innerHitsWithHighlights = InnerHits.apply().highlights(highlight("stringField")) - val innerHitsWithIncluded = InnerHits.apply().includes("intField") - val innerHitsWithName = InnerHits.apply().name("innerHitName") - val innerHitsWithSize = InnerHits.apply().size(5) + val innerHits = InnerHits() + val innerHitsWithExcluded = InnerHits().excludes("longField") + val innerHitsWithFrom = InnerHits().from(2) + val innerHitsWithHighlights = InnerHits().highlights(highlight("stringField")) + val innerHitsWithIncluded = InnerHits().includes("intField") + val innerHitsWithName = InnerHits().name("innerHitName") + val innerHitsWithSize = InnerHits().size(5) val innerHitsWithAllParams = - InnerHits - .apply() + InnerHits() .excludes("longField") + .includes("intField") .from(2) .highlights(highlight("stringField")) - .includes("intField") .name("innerHitName") .size(5) From 32c44c21d85bcf9ae08a048462ef6e57bc97b367 Mon Sep 17 00:00:00 2001 From: Dimitrije Bulaja Date: Mon, 22 May 2023 15:11:52 +0200 Subject: [PATCH 4/7] Remove prints --- .../main/scala/zio/elasticsearch/executor/HttpExecutor.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/library/src/main/scala/zio/elasticsearch/executor/HttpExecutor.scala b/modules/library/src/main/scala/zio/elasticsearch/executor/HttpExecutor.scala index 9f7be9163..0c3f6cd3b 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/executor/HttpExecutor.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/executor/HttpExecutor.scala @@ -375,8 +375,6 @@ private[elasticsearch] final class HttpExecutor private (esConfig: ElasticConfig ).flatMap { response => response.code match { case HttpOk => - println(r.toJson) - println(response.body) response.body.fold( e => ZIO.fail(new ElasticException(s"Exception occurred: ${e.getMessage}")), value => From f37f0779166ef8d3b4eb5efc0c43efffa550eb39 Mon Sep 17 00:00:00 2001 From: Dimitrije Bulaja Date: Mon, 22 May 2023 16:36:45 +0200 Subject: [PATCH 5/7] Add type-safe methods for source filtering --- .../zio/elasticsearch/query/InnerHits.scala | 31 +++++++++++++++++++ .../zio/elasticsearch/InnerHitsSpec.scala | 14 +++++---- 2 files changed, 39 insertions(+), 6 deletions(-) diff --git a/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala b/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala index 7e8b7a268..5a6a6b987 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala @@ -18,6 +18,7 @@ package zio.elasticsearch.query import zio.Chunk import zio.elasticsearch.ElasticPrimitive.ElasticPrimitiveOps +import zio.elasticsearch.Field import zio.elasticsearch.highlights.Highlights import zio.json.ast.Json import zio.json.ast.Json.{Arr, Num, Obj, Str} @@ -31,6 +32,21 @@ final case class InnerHits private[elasticsearch] ( private val size: Option[Int] ) { self => + /** + * Specifies one or more type-safe fields to be excluded in the response of a [[zio.elasticsearch.query.InnerHits]]. + * + * @param field + * a type-safe field to be excluded + * @param fields + * type-safe fields to be excluded + * @tparam S + * document which fields are excluded + * @return + * an instance of a [[zio.elasticsearch.query.InnerHits]] with specified fields to be excluded. + */ + def excludes[S](field: Field[S, _], fields: Field[S, _]*): InnerHits = + self.copy(excluded = excluded ++ (field.toString +: fields.map(_.toString))) + /** * Specifies one or more fields to be excluded in the response of a [[zio.elasticsearch.query.InnerHits]]. * @@ -66,6 +82,21 @@ final case class InnerHits private[elasticsearch] ( def highlights(value: Highlights): InnerHits = self.copy(highlights = Some(value)) + /** + * Specifies one or more type-safe fields to be included in the response of a [[zio.elasticsearch.query.InnerHits]]. + * + * @param field + * a type-safe field to be included + * @param fields + * type-safe fields to be included + * @tparam S + * document which fields are included + * @return + * an instance of a [[zio.elasticsearch.query.InnerHits]] with specified fields to be included. + */ + def includes[S](field: Field[S, _], fields: Field[S, _]*): InnerHits = + self.copy(included = included ++ (field.toString +: fields.map(_.toString))) + /** * Specifies one or more fields to be included in the response of a [[zio.elasticsearch.query.InnerHits]]. * diff --git a/modules/library/src/test/scala/zio/elasticsearch/InnerHitsSpec.scala b/modules/library/src/test/scala/zio/elasticsearch/InnerHitsSpec.scala index aece631e2..6b016f576 100644 --- a/modules/library/src/test/scala/zio/elasticsearch/InnerHitsSpec.scala +++ b/modules/library/src/test/scala/zio/elasticsearch/InnerHitsSpec.scala @@ -2,6 +2,7 @@ package zio.elasticsearch import zio.Chunk import zio.elasticsearch.ElasticHighlight.highlight +import zio.elasticsearch.domain.TestDocument import zio.elasticsearch.highlights.{HighlightField, Highlights} import zio.elasticsearch.query.InnerHits import zio.elasticsearch.utils.RichString @@ -15,10 +16,10 @@ object InnerHitsSpec extends ZIOSpecDefault { suite("InnerHits")( test("constructing") { val innerHits = InnerHits() - val innerHitsWithExcluded = InnerHits().excludes("longField") + val innerHitsWithExcluded = InnerHits().excludes(TestDocument.doubleField, TestDocument.dateField) val innerHitsWithFrom = InnerHits().from(2) val innerHitsWithHighlights = InnerHits().highlights(highlight("stringField")) - val innerHitsWithIncluded = InnerHits().includes("intField") + val innerHitsWithIncluded = InnerHits().includes(TestDocument.intField) val innerHitsWithName = InnerHits().name("innerHitName") val innerHitsWithSize = InnerHits().size(5) val innerHitsWithAllParams = @@ -37,7 +38,7 @@ object InnerHitsSpec extends ZIOSpecDefault { ) && assert(innerHitsWithExcluded)( equalTo( InnerHits( - excluded = Chunk("longField"), + excluded = Chunk("doubleField", "dateField"), included = Chunk(), from = None, highlights = None, @@ -115,10 +116,10 @@ object InnerHitsSpec extends ZIOSpecDefault { }, test("encoding as JSON") { val innerHits = InnerHits() - val innerHitsWithExcluded = InnerHits().excludes("longField") + val innerHitsWithExcluded = InnerHits().excludes(TestDocument.doubleField, TestDocument.dateField) val innerHitsWithFrom = InnerHits().from(2) val innerHitsWithHighlights = InnerHits().highlights(highlight("stringField")) - val innerHitsWithIncluded = InnerHits().includes("intField") + val innerHitsWithIncluded = InnerHits().includes(TestDocument.intField) val innerHitsWithName = InnerHits().name("innerHitName") val innerHitsWithSize = InnerHits().size(5) val innerHitsWithAllParams = @@ -145,7 +146,8 @@ object InnerHitsSpec extends ZIOSpecDefault { | "inner_hits": { | "_source" : { | "excludes" : [ - | "longField" + | "doubleField", + | "dateField" | ] | } | } From c1aa90369c010db74974d0faf7bde7a8b94d8b56 Mon Sep 17 00:00:00 2001 From: Dimitrije Bulaja Date: Mon, 22 May 2023 17:00:01 +0200 Subject: [PATCH 6/7] Fix code remark --- .../src/main/scala/zio/elasticsearch/query/InnerHits.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala b/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala index 5a6a6b987..64ebfe23c 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala @@ -135,7 +135,7 @@ final case class InnerHits private[elasticsearch] ( private[elasticsearch] def toStringJsonPair: (String, Json) = { val sourceJson: Option[Json] = (included, excluded) match { - case (included, excluded) if included.isEmpty && excluded.isEmpty => + case (Chunk.empty, Chunk.empty) => None case (included, excluded) => val includes = if (included.isEmpty) Obj() else Obj("includes" -> Arr(included.map(_.toJson))) From 5ecef6ab69814ada66a1e516696fb2a6c1b41b9d Mon Sep 17 00:00:00 2001 From: Dimitrije Bulaja Date: Mon, 22 May 2023 17:05:56 +0200 Subject: [PATCH 7/7] Fix error --- .../src/main/scala/zio/elasticsearch/query/InnerHits.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala b/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala index 64ebfe23c..73a360a78 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/query/InnerHits.scala @@ -135,7 +135,7 @@ final case class InnerHits private[elasticsearch] ( private[elasticsearch] def toStringJsonPair: (String, Json) = { val sourceJson: Option[Json] = (included, excluded) match { - case (Chunk.empty, Chunk.empty) => + case (Chunk(), Chunk()) => None case (included, excluded) => val includes = if (included.isEmpty) Obj() else Obj("includes" -> Arr(included.map(_.toJson)))