From 61ea02295b4f09138c3c6f7d198f1fd750825708 Mon Sep 17 00:00:00 2001 From: Dimitrije Bulaja Date: Tue, 23 May 2023 14:19:03 +0200 Subject: [PATCH 1/2] Refactor lib core --- .../zio/elasticsearch/ElasticRequest.scala | 134 ++++++++---- .../aggregation/Aggregations.scala | 18 +- .../zio/elasticsearch/query/Queries.scala | 196 ++++++++++++++---- .../zio/elasticsearch/query/sort/Sort.scala | 14 +- .../request/options/HasHighlights.scala | 16 ++ .../request/options/HasSearchAfter.scala | 16 ++ .../request/options/HasSourceFiltering.scala | 33 +++ .../elasticsearch/ElasticRequestSpec.scala | 90 ++++---- 8 files changed, 378 insertions(+), 139 deletions(-) create mode 100644 modules/library/src/main/scala/zio/elasticsearch/request/options/HasHighlights.scala create mode 100644 modules/library/src/main/scala/zio/elasticsearch/request/options/HasSearchAfter.scala diff --git a/modules/library/src/main/scala/zio/elasticsearch/ElasticRequest.scala b/modules/library/src/main/scala/zio/elasticsearch/ElasticRequest.scala index 960b9c566..6ae862afb 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/ElasticRequest.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/ElasticRequest.scala @@ -226,13 +226,13 @@ object ElasticRequest { */ final def search(index: IndexName, query: ElasticQuery[_]): SearchRequest = Search( + excluded = Chunk(), + included = Chunk(), index = index, query = query, sortBy = Chunk.empty, - excluded = None, from = None, highlights = None, - included = None, routing = None, searchAfter = None, size = None @@ -256,14 +256,14 @@ object ElasticRequest { aggregation: ElasticAggregation ): SearchAndAggregateRequest = SearchAndAggregate( + aggregation = aggregation, + excluded = Chunk(), + included = Chunk(), index = index, query = query, - aggregation = aggregation, sortBy = Chunk.empty, - excluded = None, from = None, highlights = None, - included = None, routing = None, searchAfter = None, size = None @@ -361,7 +361,7 @@ object ElasticRequest { private[elasticsearch] final case class Aggregate(index: IndexName, aggregation: ElasticAggregation) extends AggregateRequest { - def toJson: Json = Obj("aggs" -> aggregation.toJson) + private[elasticsearch] def toJson: Json = Obj("aggs" -> aggregation.toJson) } sealed trait BulkRequest @@ -421,7 +421,7 @@ object ElasticRequest { def routing(value: Routing): CountRequest = self.copy(routing = Some(value)) - def toJson: Json = query.fold(Obj())(q => Obj("query" -> q.toJson(fieldPath = None))) + private[elasticsearch] def toJson: Json = query.fold(Obj())(q => Obj("query" -> q.toJson(fieldPath = None))) } sealed trait CreateRequest @@ -441,7 +441,7 @@ object ElasticRequest { def routing(value: Routing): CreateRequest = self.copy(routing = Some(value)) - def toJson: Json = + private[elasticsearch] def toJson: Json = document.json } @@ -463,7 +463,7 @@ object ElasticRequest { def routing(value: Routing): CreateWithIdRequest = self.copy(routing = Some(value)) - def toJson: Json = + private[elasticsearch] def toJson: Json = document.json } @@ -473,7 +473,7 @@ object ElasticRequest { name: IndexName, definition: Option[String] ) extends CreateIndexRequest { - def toJson: String = definition.getOrElse("") + private[elasticsearch] def toJson: String = definition.getOrElse("") } sealed trait CreateOrUpdateRequest @@ -494,7 +494,7 @@ object ElasticRequest { def routing(value: Routing): CreateOrUpdateRequest = self.copy(routing = Some(value)) - def toJson: Json = + private[elasticsearch] def toJson: Json = document.json } @@ -533,7 +533,8 @@ object ElasticRequest { def routing(value: Routing): DeleteByQueryRequest = self.copy(routing = Some(value)) - def toJson: Json = Obj("query" -> query.toJson(fieldPath = None)) + private[elasticsearch] def toJson: Json = + Obj("query" -> query.toJson(fieldPath = None)) } sealed trait DeleteIndexRequest extends ElasticRequest[DeletionOutcome] @@ -572,46 +573,58 @@ object ElasticRequest { sealed trait SearchRequest extends ElasticRequest[SearchResult] with HasFrom[SearchRequest] + with HasHighlights[SearchRequest] with HasRouting[SearchRequest] + with HasSearchAfter[SearchRequest] with HasSize[SearchRequest] with HasSort[SearchRequest] with HasSourceFiltering[SearchRequest] { - def aggregate(aggregation: ElasticAggregation): SearchAndAggregateRequest - def highlights(value: Highlights): SearchRequest - - def searchAfter(value: Json): SearchRequest + /** + * Adds an [[zio.elasticsearch.aggregation.ElasticAggregation]] to the + * [[zio.elasticsearch.ElasticRequest.SearchRequest]]. + * + * @param aggregation + * the elastic aggregation to be added + * @return + * an instance of a [[zio.elasticsearch.ElasticRequest.SearchAndAggregateRequest]] that represents search and + * aggregate operations to be performed. + */ + def aggregate(aggregation: ElasticAggregation): SearchAndAggregateRequest } private[elasticsearch] final case class Search( + excluded: Chunk[String], + included: Chunk[String], index: IndexName, query: ElasticQuery[_], sortBy: Chunk[Sort], - excluded: Option[Chunk[String]], from: Option[Int], highlights: Option[Highlights], - included: Option[Chunk[String]], routing: Option[Routing], searchAfter: Option[Json], size: Option[Int] ) extends SearchRequest { self => def aggregate(aggregation: ElasticAggregation): SearchAndAggregateRequest = SearchAndAggregate( + aggregation = aggregation, + excluded = excluded, + included = included, index = index, query = query, - aggregation = aggregation, sortBy = sortBy, - excluded = excluded, from = from, highlights = highlights, - included = included, routing = routing, searchAfter = None, size = size ) + def excludes[S](field: Field[S, _], fields: Field[S, _]*): SearchRequest = + self.copy(excluded = excluded ++ (field.toString +: fields.map(_.toString))) + def excludes(field: String, fields: String*): SearchRequest = - self.copy(excluded = excluded.map(_ ++ (field +: fields)).orElse(Some(field +: Chunk.fromIterable(fields)))) + self.copy(excluded = excluded ++ (field +: fields)) def from(value: Int): SearchRequest = self.copy(from = Some(value)) @@ -619,12 +632,15 @@ object ElasticRequest { def highlights(value: Highlights): SearchRequest = self.copy(highlights = Some(value)) + def includes[S](field: Field[S, _], fields: Field[S, _]*): SearchRequest = + self.copy(included = included ++ (field.toString +: fields.map(_.toString))) + def includes(field: String, fields: String*): SearchRequest = - self.copy(included = included.map(_ ++ (field +: fields)).orElse(Some(field +: Chunk.fromIterable(fields)))) + self.copy(included = included ++ (field +: fields)) def includes[A](implicit schema: Schema.Record[A]): SearchRequest = { val fields = Chunk.fromIterable(getFieldNames(schema)) - self.copy(included = included.map(_ ++ fields).orElse(Some(fields))) + self.copy(included = included ++ fields) } def routing(value: Routing): SearchRequest = @@ -639,7 +655,7 @@ object ElasticRequest { def sort(sort: Sort, sorts: Sort*): SearchRequest = self.copy(sortBy = sortBy ++ (sort +: sorts)) - def toJson: Json = { + private[elasticsearch] def toJson: Json = { val fromJson: Json = from.fold(Obj())(f => Obj("from" -> f.toJson)) val sizeJson: Json = size.fold(Obj())(s => Obj("size" -> s.toJson)) @@ -652,11 +668,12 @@ object ElasticRequest { val sourceJson: Json = (included, excluded) match { - case (None, None) => Obj() + case (Chunk(), Chunk()) => + Obj() case (included, excluded) => Obj("_source" -> { - 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))) includes merge excludes }) } @@ -674,30 +691,31 @@ object ElasticRequest { sealed trait SearchAndAggregateRequest extends ElasticRequest[SearchAndAggregateResult] with HasFrom[SearchAndAggregateRequest] + with HasHighlights[SearchAndAggregateRequest] with HasRouting[SearchAndAggregateRequest] + with HasSearchAfter[SearchAndAggregateRequest] with HasSize[SearchAndAggregateRequest] with HasSort[SearchAndAggregateRequest] - with HasSourceFiltering[SearchAndAggregateRequest] { - def highlights(value: Highlights): SearchAndAggregateRequest - - def searchAfter(value: Json): SearchAndAggregateRequest - } + with HasSourceFiltering[SearchAndAggregateRequest] private[elasticsearch] final case class SearchAndAggregate( + aggregation: ElasticAggregation, + excluded: Chunk[String], + included: Chunk[String], index: IndexName, query: ElasticQuery[_], - aggregation: ElasticAggregation, sortBy: Chunk[Sort], - excluded: Option[Chunk[String]], from: Option[Int], highlights: Option[Highlights], - included: Option[Chunk[String]], routing: Option[Routing], searchAfter: Option[Json], size: Option[Int] ) extends SearchAndAggregateRequest { self => + def excludes[S](field: Field[S, _], fields: Field[S, _]*): SearchAndAggregateRequest = + self.copy(excluded = excluded ++ (field.toString +: fields.map(_.toString))) + def excludes(field: String, fields: String*): SearchAndAggregateRequest = - self.copy(excluded = excluded.map(_ ++ (field +: fields)).orElse(Some(field +: Chunk.fromIterable(fields)))) + self.copy(excluded = excluded ++ (field +: fields)) def from(value: Int): SearchAndAggregateRequest = self.copy(from = Some(value)) @@ -705,12 +723,15 @@ object ElasticRequest { def highlights(value: Highlights): SearchAndAggregateRequest = self.copy(highlights = Some(value)) + def includes[S](field: Field[S, _], fields: Field[S, _]*): SearchAndAggregateRequest = + self.copy(included = included ++ (field.toString +: fields.map(_.toString))) + def includes(field: String, fields: String*): SearchAndAggregateRequest = - self.copy(included = included.map(_ ++ (field +: fields)).orElse(Some(field +: Chunk.fromIterable(fields)))) + self.copy(included = included ++ (field +: fields)) def includes[A](implicit schema: Schema.Record[A]): SearchAndAggregateRequest = { val fields = Chunk.fromIterable(getFieldNames(schema)) - self.copy(included = included.map(_ ++ fields).orElse(Some(fields))) + self.copy(included = included ++ fields) } def routing(value: Routing): SearchAndAggregateRequest = @@ -725,7 +746,7 @@ object ElasticRequest { def sort(sort: Sort, sorts: Sort*): SearchAndAggregateRequest = self.copy(sortBy = sortBy ++ (sort +: sorts)) - def toJson: Json = { + private[elasticsearch] def toJson: Json = { val fromJson: Json = from.fold(Obj())(f => Obj("from" -> f.toJson)) val sizeJson: Json = size.fold(Obj())(s => Obj("size" -> s.toJson)) @@ -738,11 +759,12 @@ object ElasticRequest { val sourceJson: Json = (included, excluded) match { - case (None, None) => Obj() + case (Chunk(), Chunk()) => + Obj() case (included, excluded) => Obj("_source" -> { - 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))) includes merge excludes }) } @@ -762,6 +784,18 @@ object ElasticRequest { extends BulkableRequest[UpdateOutcome] with HasRefresh[UpdateRequest] with HasRouting[UpdateRequest] { + + /** + * Sets `upsert` parameter for [[zio.elasticsearch.ElasticRequest.UpdateRequest]] which allows creation of a + * document if it does not exists. + * + * @param doc + * the document to create if it does not exist + * @tparam A + * the type of the document, for which an implicit [[zio.schema.Schema]] is required + * @return + * an instance of the [[zio.elasticsearch.ElasticRequest.UpdateRequest]] enriched with the `upsert` parameter. + */ def orCreate[A: Schema](doc: A): UpdateRequest } @@ -783,7 +817,7 @@ object ElasticRequest { def routing(value: Routing): UpdateRequest = self.copy(routing = Some(value)) - def toJson: Json = { + private[elasticsearch] def toJson: Json = { val docToJson: Json = doc.fold(Obj())(d => Obj("doc" -> d.json)) val scriptToJson: Json = script.fold(Obj())(s => Obj("script" -> s.toJson)) @@ -798,6 +832,16 @@ object ElasticRequest { extends ElasticRequest[UpdateByQueryResult] with HasRefresh[UpdateByQueryRequest] with HasRouting[UpdateByQueryRequest] { + + /** + * Sets the conflict detection mode for the [[zio.elasticsearch.ElasticRequest.UpdateByQueryRequest]]. + * + * @param value + * the [[zio.elasticsearch.request.UpdateConflicts]] value to be set + * @return + * an instance of the [[zio.elasticsearch.ElasticRequest.UpdateByQueryRequest]] with the conflict detection mode + * configured. + */ def conflicts(value: UpdateConflicts): UpdateByQueryRequest } @@ -818,7 +862,7 @@ object ElasticRequest { def routing(value: Routing): UpdateByQueryRequest = self.copy(routing = Some(value)) - def toJson: Json = + private[elasticsearch] def toJson: Json = query.foldLeft(Obj("script" -> script.toJson))((scriptJson, q) => scriptJson merge Obj("query" -> q.toJson(fieldPath = None)) ) diff --git a/modules/library/src/main/scala/zio/elasticsearch/aggregation/Aggregations.scala b/modules/library/src/main/scala/zio/elasticsearch/aggregation/Aggregations.scala index de2b74e44..b2a24e38d 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/aggregation/Aggregations.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/aggregation/Aggregations.scala @@ -77,8 +77,7 @@ private[elasticsearch] final case class BucketSort( sortBy: Chunk[Sort], from: Option[Int], size: Option[Int] -) extends BucketSortAggregation { - self => +) extends BucketSortAggregation { self => def from(value: Int): BucketSortAggregation = self.copy(from = Some(value)) @@ -141,6 +140,15 @@ private[elasticsearch] final case class Max(name: String, field: String, missing } sealed trait MultipleAggregations extends ElasticAggregation with WithAgg { + + /** + * Sets the aggregations for the [[zio.elasticsearch.aggregation.MultipleAggregations]]. + * + * @param aggregations + * the aggregations to be set + * @return + * an instance of the [[zio.elasticsearch.aggregation.MultipleAggregations]] with the specified aggregations. + */ def aggregations(aggregations: SingleElasticAggregation*): MultipleAggregations } @@ -149,11 +157,11 @@ private[elasticsearch] final case class Multiple(aggregations: Chunk[SingleElast def aggregations(aggregations: SingleElasticAggregation*): MultipleAggregations = self.copy(aggregations = self.aggregations ++ aggregations) - private[elasticsearch] def toJson: Json = - aggregations.map(_.toJson).reduce(_ merge _) - def withAgg(agg: SingleElasticAggregation): MultipleAggregations = self.copy(aggregations = agg +: aggregations) + + private[elasticsearch] def toJson: Json = + aggregations.map(_.toJson).reduce(_ merge _) } sealed trait TermsAggregation diff --git a/modules/library/src/main/scala/zio/elasticsearch/query/Queries.scala b/modules/library/src/main/scala/zio/elasticsearch/query/Queries.scala index 3c60c0f7e..1c6219c1d 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/query/Queries.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/query/Queries.scala @@ -31,20 +31,101 @@ sealed trait ElasticQuery[-S] { self => } sealed trait BoolQuery[S] extends ElasticQuery[S] with HasBoost[BoolQuery[S]] with HasMinimumShouldMatch[BoolQuery[S]] { + + /** + * Adds specified `filter` queries to the [[zio.elasticsearch.query.BoolQuery]]. These queries must appear in matching + * documents. Unlike `must` the score of the query will be ignored. + * + * @param queries + * the `filter` queries to be added + * @tparam S1 + * the type of the sub-queries, for which an implicit [[zio.schema.Schema]] is required + * @return + * an instance of the [[zio.elasticsearch.query.BoolQuery]] with `filter` queries added. + */ def filter[S1 <: S: Schema](queries: ElasticQuery[S1]*): BoolQuery[S1] + /** + * Adds specified `filter` queries to the [[zio.elasticsearch.query.BoolQuery]]. These queries must appear in matching + * documents. Unlike `must` the score of the query will be ignored. + * + * @param queries + * the `filter` queries to be added + * @return + * an instance of the [[zio.elasticsearch.query.BoolQuery]] with `filter` queries added. + */ def filter(queries: ElasticQuery[Any]*): BoolQuery[S] + /** + * Adds specified `must` queries to the [[zio.elasticsearch.query.BoolQuery]]. These queries must appear in matching + * documents and will contribute to the score. + * + * @param queries + * the `must` queries to be added + * @tparam S1 + * the type of the sub-queries, for which an implicit [[zio.schema.Schema]] is required + * @return + * an instance of the [[zio.elasticsearch.query.BoolQuery]] with `must` queries added. + */ def must[S1 <: S: Schema](queries: ElasticQuery[S1]*): BoolQuery[S1] + /** + * Adds specified `must` queries to the [[zio.elasticsearch.query.BoolQuery]]. These queries must appear in matching + * documents and will contribute to the score. + * + * @param queries + * the `must` queries to be added + * @return + * an instance of the [[zio.elasticsearch.query.BoolQuery]] with `must` queries added. + */ def must(queries: ElasticQuery[Any]*): BoolQuery[S] + /** + * Adds specified `must not` queries to the [[zio.elasticsearch.query.BoolQuery]]. These queries must not appear in + * matching documents. + * + * @param queries + * the `must not` queries to be added + * @tparam S1 + * the type of the sub-queries, for which an implicit [[zio.schema.Schema]] is required + * @return + * an instance of the [[zio.elasticsearch.query.BoolQuery]] with `must not` queries added. + */ def mustNot[S1 <: S: Schema](queries: ElasticQuery[S1]*): BoolQuery[S1] + /** + * Adds specified `must not` queries to the [[zio.elasticsearch.query.BoolQuery]]. These queries must not appear in + * matching documents. + * + * @param queries + * the `must not` queries to be added + * @return + * an instance of the [[zio.elasticsearch.query.BoolQuery]] with `must not` queries added. + */ def mustNot(queries: ElasticQuery[Any]*): BoolQuery[S] + /** + * Adds specified `should` queries to the [[zio.elasticsearch.query.BoolQuery]]. These queries should appear in + * matching documents. + * + * @param queries + * the `should` queries to be added + * @tparam S1 + * the type of the sub-queries, for which an implicit [[zio.schema.Schema]] is required + * @return + * an instance of the [[zio.elasticsearch.query.BoolQuery]] with `should` queries added. + */ def should[S1 <: S: Schema](queries: ElasticQuery[S1]*): BoolQuery[S1] + /** + * Adds specified `should` queries to the [[zio.elasticsearch.query.BoolQuery]]. These queries should appear in + * matching documents. + * + * @param queries + * the `should` queries to be added + * @return + * an instance of the [[zio.elasticsearch.query.BoolQuery]] with `should` queries added. + */ def should(queries: ElasticQuery[Any]*): BoolQuery[S] } @@ -80,7 +161,13 @@ private[elasticsearch] final case class Bool[S]( def mustNot(queries: ElasticQuery[Any]*): BoolQuery[S] = self.copy(mustNot = mustNot ++ queries) - def toJson(fieldPath: Option[String]): Json = { + def should[S1 <: S: Schema](queries: ElasticQuery[S1]*): BoolQuery[S1] = + self.copy(should = should ++ queries) + + def should(queries: ElasticQuery[Any]*): BoolQuery[S] = + self.copy(should = should ++ queries) + + private[elasticsearch] def toJson(fieldPath: Option[String]): Json = { val boolFields = Chunk( if (filter.nonEmpty) Some("filter" -> Arr(filter.map(_.toJson(fieldPath)))) else None, @@ -93,18 +180,12 @@ private[elasticsearch] final case class Bool[S]( Obj("bool" -> Obj(boolFields)) } - - def should[S1 <: S: Schema](queries: ElasticQuery[S1]*): BoolQuery[S1] = - self.copy(should = should ++ queries) - - def should(queries: ElasticQuery[Any]*): BoolQuery[S] = - self.copy(should = should ++ queries) } sealed trait ExistsQuery[S] extends ElasticQuery[S] private[elasticsearch] final case class Exists[S](field: String) extends ExistsQuery[S] { - def toJson(fieldPath: Option[String]): Json = + private[elasticsearch] def toJson(fieldPath: Option[String]): Json = Obj("exists" -> Obj("field" -> fieldPath.foldRight(field)(_ + "." + _).toJson)) } @@ -181,7 +262,9 @@ private[elasticsearch] final case class GeoDistance[S]( def name(value: String): GeoDistanceQuery[S] = self.copy(queryName = Some(value)) - def toJson(fieldPath: Option[String]): Json = + def validationMethod(value: ValidationMethod): GeoDistanceQuery[S] = self.copy(validationMethod = Some(value)) + + private[elasticsearch] def toJson(fieldPath: Option[String]): Json = Obj( "geo_distance" -> Obj( Chunk( @@ -194,7 +277,6 @@ private[elasticsearch] final case class GeoDistance[S]( ) ) - def validationMethod(value: ValidationMethod): GeoDistanceQuery[S] = self.copy(validationMethod = Some(value)) } sealed trait HasChildQuery[S] @@ -250,7 +332,10 @@ private[elasticsearch] final case class HasChild[S]( def minChildren(value: Int): HasChildQuery[S] = self.copy(minChildren = Some(value)) - def toJson(fieldPath: Option[String]): Json = + def scoreMode(value: ScoreMode): HasChildQuery[S] = + self.copy(scoreMode = Some(value)) + + private[elasticsearch] def toJson(fieldPath: Option[String]): Json = Obj( "has_child" -> Obj( Chunk( @@ -264,9 +349,6 @@ private[elasticsearch] final case class HasChild[S]( ).flatten ) ) - - def scoreMode(value: ScoreMode): HasChildQuery[S] = - self.copy(scoreMode = Some(value)) } sealed trait HasParentQuery[S] @@ -322,7 +404,10 @@ private[elasticsearch] final case class HasParent[S]( def innerHits(innerHits: InnerHits): HasParentQuery[S] = self.copy(innerHitsField = Some(innerHits)) - def toJson(fieldPath: Option[String]): Json = + def withScore(value: Boolean): HasParent[S] = + self.copy(score = Some(value)) + + private[elasticsearch] def toJson(fieldPath: Option[String]): Json = Obj( "has_parent" -> Obj( Chunk( @@ -334,15 +419,12 @@ private[elasticsearch] final case class HasParent[S]( ).flatten ) ) - - def withScore(value: Boolean): HasParent[S] = - self.copy(score = Some(value)) } sealed trait MatchQuery[S] extends ElasticQuery[S] private[elasticsearch] final case class Match[S, A: ElasticPrimitive](field: String, value: A) extends MatchQuery[S] { - def toJson(fieldPath: Option[String]): Json = + private[elasticsearch] def toJson(fieldPath: Option[String]): Json = Obj("match" -> Obj(fieldPath.foldRight(field)(_ + "." + _) -> value.toJson)) } @@ -352,14 +434,14 @@ private[elasticsearch] final case class MatchAll(boost: Option[Double]) extends def boost(value: Double): MatchAllQuery = self.copy(boost = Some(value)) - def toJson(fieldPath: Option[String]): Json = + private[elasticsearch] def toJson(fieldPath: Option[String]): Json = Obj("match_all" -> Obj(Chunk.fromIterable(boost.map("boost" -> Num(_))))) } sealed trait MatchPhraseQuery[S] extends ElasticQuery[S] private[elasticsearch] final case class MatchPhrase[S](field: String, value: String) extends MatchPhraseQuery[S] { - def toJson(fieldPath: Option[String]): Json = + private[elasticsearch] def toJson(fieldPath: Option[String]): Json = Obj("match_phrase" -> Obj(fieldPath.foldRight(field)(_ + "." + _) -> value.toJson)) } @@ -382,7 +464,10 @@ private[elasticsearch] final case class Nested[S]( def innerHits(innerHits: InnerHits): NestedQuery[S] = self.copy(innerHitsField = Some(innerHits)) - def toJson(fieldPath: Option[String]): Json = + def scoreMode(scoreMode: ScoreMode): NestedQuery[S] = + self.copy(scoreMode = Some(scoreMode)) + + private[elasticsearch] def toJson(fieldPath: Option[String]): Json = Obj( "nested" -> Obj( Chunk( @@ -394,55 +479,94 @@ private[elasticsearch] final case class Nested[S]( ).flatten ) ) - - def scoreMode(scoreMode: ScoreMode): NestedQuery[S] = - self.copy(scoreMode = Some(scoreMode)) } sealed trait LowerBound { - def toJson: Option[(String, Json)] + private[elasticsearch] def toJson: Option[(String, Json)] } private[elasticsearch] final case class GreaterThan[A: ElasticPrimitive](value: A) extends LowerBound { - def toJson: Option[(String, Json)] = Some("gt" -> value.toJson) + private[elasticsearch] def toJson: Option[(String, Json)] = Some("gt" -> value.toJson) } private[elasticsearch] final case class GreaterThanOrEqualTo[A: ElasticPrimitive](value: A) extends LowerBound { - def toJson: Option[(String, Json)] = Some("gte" -> value.toJson) + private[elasticsearch] def toJson: Option[(String, Json)] = Some("gte" -> value.toJson) } sealed trait UpperBound { - def toJson: Option[(String, Json)] + private[elasticsearch] def toJson: Option[(String, Json)] } private[elasticsearch] final case class LessThan[A: ElasticPrimitive](value: A) extends UpperBound { - def toJson: Option[(String, Json)] = Some("lt" -> value.toJson) + private[elasticsearch] def toJson: Option[(String, Json)] = Some("lt" -> value.toJson) } private[elasticsearch] final case class LessThanOrEqualTo[A: ElasticPrimitive](value: A) extends UpperBound { - def toJson: Option[(String, Json)] = Some("lte" -> value.toJson) + private[elasticsearch] def toJson: Option[(String, Json)] = Some("lte" -> value.toJson) } private[elasticsearch] case object Unbounded extends LowerBound with UpperBound { - def toJson: Option[(String, Json)] = None + private[elasticsearch] def toJson: Option[(String, Json)] = None } sealed trait RangeQuery[S, A, LB <: LowerBound, UB <: UpperBound] extends ElasticQuery[S] with HasBoost[RangeQuery[S, A, LB, UB]] with HasFormat[RangeQuery[S, A, LB, UB]] { + + /** + * Sets the greater-than bound for the [[zio.elasticsearch.query.RangeQuery]]. + * + * @param value + * the value for the greater-than bound + * @tparam B + * the type of the value, constrained by the [[zio.elasticsearch.ElasticPrimitive]] + * @return + * a new instance of the [[zio.elasticsearch.query.RangeQuery]] enriched with the greater-than bound set. + */ def gt[B <: A: ElasticPrimitive](value: B)(implicit @unused ev: LB =:= Unbounded.type ): RangeQuery[S, B, GreaterThan[B], UB] + /** + * Sets the greater-than-or-equal-to bound for the [[zio.elasticsearch.query.RangeQuery]]. + * + * @param value + * the value for the greater-than-or-equal-to bound + * @tparam B + * the type of the value, constrained by the [[zio.elasticsearch.ElasticPrimitive]] + * @return + * a new instance of the [[zio.elasticsearch.query.RangeQuery]] enriched with the greater-than-or-equal-to bound + * set. + */ def gte[B <: A: ElasticPrimitive](value: B)(implicit @unused ev: LB =:= Unbounded.type ): RangeQuery[S, B, GreaterThanOrEqualTo[B], UB] + /** + * Sets the less-than bound for the [[zio.elasticsearch.query.RangeQuery]]. + * + * @param value + * the value for the less-than bound + * @tparam B + * the type of the value, constrained by the [[zio.elasticsearch.ElasticPrimitive]] + * @return + * a new instance of the [[zio.elasticsearch.query.RangeQuery]] enriched with the less-than bound set. + */ def lt[B <: A: ElasticPrimitive](value: B)(implicit @unused ev: UB =:= Unbounded.type ): RangeQuery[S, B, LB, LessThan[B]] + /** + * Sets the less-than-or-equal-to bound for the [[zio.elasticsearch.query.RangeQuery]]. + * + * @param value + * the value for the less-than-or-equal-to bound + * @tparam B + * the type of the value, constrained by the [[zio.elasticsearch.ElasticPrimitive]] + * @return + * a new instance of the [[zio.elasticsearch.query.RangeQuery]] enriched with the less-than-or-equal-to bound set. + */ def lte[B <: A: ElasticPrimitive](value: B)(implicit @unused ev: UB =:= Unbounded.type ): RangeQuery[S, B, LB, LessThanOrEqualTo[B]] @@ -481,7 +605,7 @@ private[elasticsearch] final case class Range[S, A, LB <: LowerBound, UB <: Uppe ): RangeQuery[S, B, LB, LessThanOrEqualTo[B]] = self.copy(upper = LessThanOrEqualTo(value)) - def toJson(fieldPath: Option[String]): Json = + private[elasticsearch] def toJson(fieldPath: Option[String]): Json = Obj( "range" -> Obj( fieldPath.foldRight(field)(_ + "." + _) -> Obj( @@ -521,7 +645,7 @@ private[elasticsearch] final case class Term[S]( def caseInsensitive(value: Boolean): TermQuery[S] = self.copy(caseInsensitive = Some(value)) - def toJson(fieldPath: Option[String]): Json = { + private[elasticsearch] def toJson(fieldPath: Option[String]): Json = { val termFields = Some("value" -> value.toJson) ++ boost.map("boost" -> Num(_)) ++ caseInsensitive.map( "case_insensitive" -> Json.Bool(_) ) @@ -539,7 +663,7 @@ private[elasticsearch] final case class Terms[S]( def boost(value: Double): TermsQuery[S] = self.copy(boost = Some(value)) - def toJson(fieldPath: Option[String]): Json = { + private[elasticsearch] def toJson(fieldPath: Option[String]): Json = { val termsFields = Some(fieldPath.foldRight(field)(_ + "." + _) -> Arr(values.map(Str(_)))) ++ boost.map("boost" -> Num(_)) Obj("terms" -> Obj(Chunk.fromIterable(termsFields))) @@ -563,7 +687,7 @@ private[elasticsearch] final case class Wildcard[S]( def caseInsensitive(value: Boolean): WildcardQuery[S] = self.copy(caseInsensitive = Some(value)) - def toJson(fieldPath: Option[String]): Json = { + private[elasticsearch] def toJson(fieldPath: Option[String]): Json = { val wildcardFields = Some("value" -> value.toJson) ++ boost.map("boost" -> Num(_)) ++ caseInsensitive.map( "case_insensitive" -> Json.Bool(_) ) diff --git a/modules/library/src/main/scala/zio/elasticsearch/query/sort/Sort.scala b/modules/library/src/main/scala/zio/elasticsearch/query/sort/Sort.scala index 566a39444..b9a69af13 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/query/sort/Sort.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/query/sort/Sort.scala @@ -34,9 +34,7 @@ sealed trait SortByField with HasMode[SortByField] with HasNumericType[SortByField] with HasOrder[SortByField] - with HasUnmappedType[SortByField] { - def toJson: Json -} + with HasUnmappedType[SortByField] object SortByField { @@ -129,7 +127,10 @@ private[elasticsearch] final case class SortByFieldOptions( def order(value: SortOrder): SortByField = self.copy(order = Some(value)) - def toJson: Json = { + def unmappedType(value: String): SortByField = + self.copy(unmappedType = Some(value)) + + private[elasticsearch] def toJson: Json = { val allParams = Chunk( self.order.map(order => "order" -> order.toString.toJson), self.format.map(format => "format" -> format.toJson), @@ -141,9 +142,6 @@ private[elasticsearch] final case class SortByFieldOptions( if (allParams.isEmpty) self.field.toJson else Obj(self.field -> Obj(allParams)) } - - def unmappedType(value: String): SortByField = - self.copy(unmappedType = Some(value)) } sealed trait SortByScript extends Sort with HasMode[SortByScript] with HasOrder[SortByScript] @@ -160,7 +158,7 @@ private[elasticsearch] final case class SortByScriptOptions( def order(value: SortOrder): SortByScript = self.copy(order = Some(value)) - def toJson: Json = + private[elasticsearch] def toJson: Json = Obj( "_script" -> Obj( Chunk( diff --git a/modules/library/src/main/scala/zio/elasticsearch/request/options/HasHighlights.scala b/modules/library/src/main/scala/zio/elasticsearch/request/options/HasHighlights.scala new file mode 100644 index 000000000..36cdebaed --- /dev/null +++ b/modules/library/src/main/scala/zio/elasticsearch/request/options/HasHighlights.scala @@ -0,0 +1,16 @@ +package zio.elasticsearch.request.options + +import zio.elasticsearch.highlights.Highlights + +private[elasticsearch] trait HasHighlights[R <: HasHighlights[R]] { + + /** + * Sets the [[zio.elasticsearch.highlights.Highlights]] for the [[zio.elasticsearch.ElasticRequest]]. + * + * @param value + * the [[zio.elasticsearch.highlights.Highlights]] to be set + * @return + * an instance of the [[zio.elasticsearch.ElasticRequest]] enriched with the highlights. + */ + def highlights(value: Highlights): R +} diff --git a/modules/library/src/main/scala/zio/elasticsearch/request/options/HasSearchAfter.scala b/modules/library/src/main/scala/zio/elasticsearch/request/options/HasSearchAfter.scala new file mode 100644 index 000000000..7fbb5c72e --- /dev/null +++ b/modules/library/src/main/scala/zio/elasticsearch/request/options/HasSearchAfter.scala @@ -0,0 +1,16 @@ +package zio.elasticsearch.request.options + +import zio.json.ast.Json + +private[elasticsearch] trait HasSearchAfter[R <: HasSearchAfter[R]] { + + /** + * Sets the `search_after` parameter for the [[zio.elasticsearch.ElasticRequest]]. + * + * @param value + * the JSON value to be set as the `search_after` parameter + * @return + * an instance of a [[zio.elasticsearch.ElasticRequest]] enriched with the `search_after` parameter. + */ + def searchAfter(value: Json): R +} diff --git a/modules/library/src/main/scala/zio/elasticsearch/request/options/HasSourceFiltering.scala b/modules/library/src/main/scala/zio/elasticsearch/request/options/HasSourceFiltering.scala index 3a701354c..5e1139e16 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/request/options/HasSourceFiltering.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/request/options/HasSourceFiltering.scala @@ -17,10 +17,28 @@ package zio.elasticsearch.request.options import zio.Chunk +import zio.elasticsearch.Field import zio.schema.Schema private[elasticsearch] trait HasSourceFiltering[R <: HasSourceFiltering[R]] { + /** + * Specifies one or more type-safe fields to be excluded in the response of a + * [[zio.elasticsearch.ElasticRequest.SearchRequest]] or a + * [[zio.elasticsearch.ElasticRequest.SearchAndAggregateRequest]]. + * + * @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.ElasticRequest.SearchRequest]] or a + * [[zio.elasticsearch.ElasticRequest.SearchAndAggregateRequest]] with specified fields to be excluded. + */ + def excludes[S](field: Field[S, _], fields: Field[S, _]*): R + /** * Specifies one or more fields to be excluded in the response of a [[zio.elasticsearch.ElasticRequest.SearchRequest]] * or a [[zio.elasticsearch.ElasticRequest.SearchAndAggregateRequest]]. @@ -35,6 +53,21 @@ private[elasticsearch] trait HasSourceFiltering[R <: HasSourceFiltering[R]] { */ def excludes(field: String, fields: String*): R + /** + * Specifies one or more type-safe fields to be included in the response of a + * [[zio.elasticsearch.ElasticRequest.SearchRequest]] or a + * [[zio.elasticsearch.ElasticRequest.SearchAndAggregateRequest]]. + * + * @param field + * a type-safe field to be included + * @param fields + * type-safe fields to be included + * @return + * an instance of a [[zio.elasticsearch.ElasticRequest.SearchRequest]] or a + * [[zio.elasticsearch.ElasticRequest.SearchAndAggregateRequest]] with specified fields to be included. + */ + def includes[S](field: Field[S, _], fields: Field[S, _]*): R + /** * Specifies one or more fields to be included in the response of a [[zio.elasticsearch.ElasticRequest.SearchRequest]] * or a [[zio.elasticsearch.ElasticRequest.SearchAndAggregateRequest]]. diff --git a/modules/library/src/test/scala/zio/elasticsearch/ElasticRequestSpec.scala b/modules/library/src/test/scala/zio/elasticsearch/ElasticRequestSpec.scala index c62e0016f..7ca776b83 100644 --- a/modules/library/src/test/scala/zio/elasticsearch/ElasticRequestSpec.scala +++ b/modules/library/src/test/scala/zio/elasticsearch/ElasticRequestSpec.scala @@ -284,13 +284,13 @@ object ElasticRequestSpec extends ZIOSpecDefault { assert(searchRequest)( equalTo( Search( + excluded = Chunk(), + included = Chunk(), index = Index, query = Query, sortBy = Chunk.empty, - excluded = None, from = None, highlights = None, - included = None, routing = None, searchAfter = None, size = None @@ -299,6 +299,8 @@ object ElasticRequestSpec extends ZIOSpecDefault { ) && assert(searchRequestWithSort)( equalTo( Search( + excluded = Chunk(), + included = Chunk(), index = Index, query = Query, sortBy = Chunk( @@ -312,10 +314,8 @@ object ElasticRequestSpec extends ZIOSpecDefault { unmappedType = None ) ), - excluded = None, from = None, highlights = None, - included = None, routing = None, searchAfter = None, size = None @@ -324,13 +324,13 @@ object ElasticRequestSpec extends ZIOSpecDefault { ) && assert(searchRequestWithSourceFiltering)( equalTo( Search( + excluded = Chunk("booleanField"), + included = Chunk("stringField", "doubleField"), index = Index, query = Query, sortBy = Chunk.empty, - excluded = Some(Chunk("booleanField")), from = None, highlights = None, - included = Some(Chunk("stringField", "doubleField")), routing = None, searchAfter = None, size = None @@ -339,13 +339,13 @@ object ElasticRequestSpec extends ZIOSpecDefault { ) && assert(searchRequestWithFrom)( equalTo( Search( + excluded = Chunk(), + included = Chunk(), index = Index, query = Query, sortBy = Chunk.empty, - excluded = None, from = Some(5), highlights = None, - included = None, routing = None, searchAfter = None, size = None @@ -354,15 +354,15 @@ object ElasticRequestSpec extends ZIOSpecDefault { ) && assert(searchRequestWithHighlights)( equalTo( Search( + excluded = Chunk(), + included = Chunk(), index = Index, query = Query, sortBy = Chunk.empty, - excluded = None, from = None, highlights = Some( Highlights(fields = Chunk(HighlightField(field = "intField", config = Map.empty)), config = Map.empty) ), - included = None, routing = None, searchAfter = None, size = None @@ -371,13 +371,13 @@ object ElasticRequestSpec extends ZIOSpecDefault { ) && assert(searchRequestWithRouting)( equalTo( Search( + excluded = Chunk(), + included = Chunk(), index = Index, query = Query, sortBy = Chunk.empty, - excluded = None, from = None, highlights = None, - included = None, routing = Some(RoutingValue), searchAfter = None, size = None @@ -386,13 +386,13 @@ object ElasticRequestSpec extends ZIOSpecDefault { ) && assert(searchRequestWithSearchAfter)( equalTo( Search( + excluded = Chunk(), + included = Chunk(), index = Index, query = Query, sortBy = Chunk.empty, - excluded = None, from = None, highlights = None, - included = None, routing = None, searchAfter = Some(Arr(Str("12345"))), size = None @@ -401,13 +401,13 @@ object ElasticRequestSpec extends ZIOSpecDefault { ) && assert(searchRequestWithSize)( equalTo( Search( + excluded = Chunk(), + included = Chunk(), index = Index, query = Query, sortBy = Chunk.empty, - excluded = None, from = None, highlights = None, - included = None, routing = None, searchAfter = None, size = Some(5) @@ -416,6 +416,8 @@ object ElasticRequestSpec extends ZIOSpecDefault { ) && assert(searchRequestWithAllParams)( equalTo( Search( + excluded = Chunk("booleanField"), + included = Chunk("stringField", "doubleField"), index = Index, query = Query, sortBy = Chunk( @@ -429,12 +431,10 @@ object ElasticRequestSpec extends ZIOSpecDefault { unmappedType = None ) ), - excluded = Some(Chunk("booleanField")), from = Some(5), highlights = Some( Highlights(fields = Chunk(HighlightField(field = "intField", config = Map.empty)), config = Map.empty) ), - included = Some(Chunk("stringField", "doubleField")), routing = Some(RoutingValue), searchAfter = Some(Arr(Str("12345"))), size = Some(5) @@ -473,14 +473,14 @@ object ElasticRequestSpec extends ZIOSpecDefault { assert(searchAndAggRequest)( equalTo( SearchAndAggregate( + aggregation = MaxAggregation, + excluded = Chunk(), + included = Chunk(), index = Index, query = Query, - aggregation = MaxAggregation, sortBy = Chunk.empty, - excluded = None, from = None, highlights = None, - included = None, routing = None, searchAfter = None, size = None @@ -489,9 +489,11 @@ object ElasticRequestSpec extends ZIOSpecDefault { ) && assert(searchAndAggRequestWithSort)( equalTo( SearchAndAggregate( + aggregation = MaxAggregation, + excluded = Chunk(), + included = Chunk(), index = Index, query = Query, - aggregation = MaxAggregation, sortBy = Chunk( SortByFieldOptions( field = "intField", @@ -503,10 +505,8 @@ object ElasticRequestSpec extends ZIOSpecDefault { unmappedType = None ) ), - excluded = None, from = None, highlights = None, - included = None, routing = None, searchAfter = None, size = None @@ -515,14 +515,14 @@ object ElasticRequestSpec extends ZIOSpecDefault { ) && assert(searchAndAggRequestWithSourceFiltering)( equalTo( SearchAndAggregate( + aggregation = MaxAggregation, + excluded = Chunk("booleanField"), + included = Chunk("stringField", "doubleField"), index = Index, query = Query, - aggregation = MaxAggregation, sortBy = Chunk.empty, - excluded = Some(Chunk("booleanField")), from = None, highlights = None, - included = Some(Chunk("stringField", "doubleField")), routing = None, searchAfter = None, size = None @@ -531,14 +531,14 @@ object ElasticRequestSpec extends ZIOSpecDefault { ) && assert(searchAndAggRequestWithFrom)( equalTo( SearchAndAggregate( + aggregation = MaxAggregation, + excluded = Chunk(), + included = Chunk(), index = Index, query = Query, - aggregation = MaxAggregation, sortBy = Chunk.empty, - excluded = None, from = Some(5), highlights = None, - included = None, routing = None, searchAfter = None, size = None @@ -547,16 +547,16 @@ object ElasticRequestSpec extends ZIOSpecDefault { ) && assert(searchAndAggRequestWithHighlights)( equalTo( SearchAndAggregate( + aggregation = MaxAggregation, + excluded = Chunk(), + included = Chunk(), index = Index, query = Query, - aggregation = MaxAggregation, sortBy = Chunk.empty, - excluded = None, from = None, highlights = Some( Highlights(fields = Chunk(HighlightField(field = "intField", config = Map.empty)), config = Map.empty) ), - included = None, routing = None, searchAfter = None, size = None @@ -565,14 +565,14 @@ object ElasticRequestSpec extends ZIOSpecDefault { ) && assert(searchAndAggRequestWithRouting)( equalTo( SearchAndAggregate( + aggregation = MaxAggregation, + excluded = Chunk(), + included = Chunk(), index = Index, query = Query, - aggregation = MaxAggregation, sortBy = Chunk.empty, - excluded = None, from = None, highlights = None, - included = None, routing = Some(RoutingValue), searchAfter = None, size = None @@ -581,14 +581,14 @@ object ElasticRequestSpec extends ZIOSpecDefault { ) && assert(searchAndAggRequestWithSearchAfter)( equalTo( SearchAndAggregate( + aggregation = MaxAggregation, + excluded = Chunk(), + included = Chunk(), index = Index, query = Query, - aggregation = MaxAggregation, sortBy = Chunk.empty, - excluded = None, from = None, highlights = None, - included = None, routing = None, searchAfter = Some(Arr(Str("12345"))), size = None @@ -597,14 +597,14 @@ object ElasticRequestSpec extends ZIOSpecDefault { ) && assert(searchAndAggRequestWithSize)( equalTo( SearchAndAggregate( + aggregation = MaxAggregation, + excluded = Chunk(), + included = Chunk(), index = Index, query = Query, - aggregation = MaxAggregation, sortBy = Chunk.empty, - excluded = None, from = None, highlights = None, - included = None, routing = None, searchAfter = None, size = Some(5) @@ -613,9 +613,11 @@ object ElasticRequestSpec extends ZIOSpecDefault { ) && assert(searchAndAggRequestWithAllParams)( equalTo( SearchAndAggregate( + aggregation = MaxAggregation, + excluded = Chunk("booleanField"), + included = Chunk("stringField", "doubleField"), index = Index, query = Query, - aggregation = MaxAggregation, sortBy = Chunk( SortByFieldOptions( field = "intField", @@ -627,12 +629,10 @@ object ElasticRequestSpec extends ZIOSpecDefault { unmappedType = None ) ), - excluded = Some(Chunk("booleanField")), from = Some(5), highlights = Some( Highlights(fields = Chunk(HighlightField(field = "intField", config = Map.empty)), config = Map.empty) ), - included = Some(Chunk("stringField", "doubleField")), routing = Some(RoutingValue), searchAfter = Some(Arr(Str("12345"))), size = Some(5) From 7da07a3cd68dcbd2184ad8b6f05f560fe04a2df0 Mon Sep 17 00:00:00 2001 From: Dimitrije Bulaja Date: Tue, 23 May 2023 14:25:58 +0200 Subject: [PATCH 2/2] Fix lint --- .../request/options/HasHighlights.scala | 16 ++++++++++++++++ .../request/options/HasSearchAfter.scala | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/modules/library/src/main/scala/zio/elasticsearch/request/options/HasHighlights.scala b/modules/library/src/main/scala/zio/elasticsearch/request/options/HasHighlights.scala index 36cdebaed..e27ee4a5d 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/request/options/HasHighlights.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/request/options/HasHighlights.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2022 LambdaWorks + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package zio.elasticsearch.request.options import zio.elasticsearch.highlights.Highlights diff --git a/modules/library/src/main/scala/zio/elasticsearch/request/options/HasSearchAfter.scala b/modules/library/src/main/scala/zio/elasticsearch/request/options/HasSearchAfter.scala index 7fbb5c72e..00fbbfacf 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/request/options/HasSearchAfter.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/request/options/HasSearchAfter.scala @@ -1,3 +1,19 @@ +/* + * Copyright 2022 LambdaWorks + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package zio.elasticsearch.request.options import zio.json.ast.Json