diff --git a/docs/overview/queries/elastic_query_match_phrase.md b/docs/overview/queries/elastic_query_match_phrase.md new file mode 100644 index 000000000..1b0a161cc --- /dev/null +++ b/docs/overview/queries/elastic_query_match_phrase.md @@ -0,0 +1,6 @@ +--- +id: elastic_query_match_phrase +title: "Match Phrase Query" +--- + +TBD diff --git a/modules/example/src/main/scala/example/api/ErrorResponse.scala b/modules/example/src/main/scala/example/api/ErrorResponse.scala new file mode 100644 index 000000000..08cb5fe3c --- /dev/null +++ b/modules/example/src/main/scala/example/api/ErrorResponse.scala @@ -0,0 +1,29 @@ +/* + * 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 example.api + +import zio.Chunk +import zio.json.{DeriveJsonEncoder, JsonEncoder} + +final case class ErrorResponse(errors: ErrorResponseData) + +object ErrorResponse { + implicit val encoder: JsonEncoder[ErrorResponse] = DeriveJsonEncoder.gen[ErrorResponse] + + def fromReasons(reasons: String*): ErrorResponse = + new ErrorResponse(ErrorResponseData(Chunk.fromIterable(reasons))) +} diff --git a/modules/example/src/main/scala/example/api/ErrorResponseData.scala b/modules/example/src/main/scala/example/api/ErrorResponseData.scala new file mode 100644 index 000000000..c31fc4bf6 --- /dev/null +++ b/modules/example/src/main/scala/example/api/ErrorResponseData.scala @@ -0,0 +1,26 @@ +/* + * 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 example.api + +import zio.Chunk +import zio.json.{DeriveJsonEncoder, JsonEncoder} + +final case class ErrorResponseData(body: Chunk[String]) + +object ErrorResponseData { + implicit val encoder: JsonEncoder[ErrorResponseData] = DeriveJsonEncoder.gen[ErrorResponseData] +} diff --git a/modules/example/src/main/scala/example/api/package.scala b/modules/example/src/main/scala/example/api/package.scala index 3cf0c064c..6cb6e3b87 100644 --- a/modules/example/src/main/scala/example/api/package.scala +++ b/modules/example/src/main/scala/example/api/package.scala @@ -16,31 +16,12 @@ package example -import zio.Chunk import zio.http.Request -import zio.json._ package object api { - - final case class ErrorResponseData(body: Chunk[String]) - - object ErrorResponseData { - implicit val encoder: JsonEncoder[ErrorResponseData] = DeriveJsonEncoder.gen[ErrorResponseData] - } - - final case class ErrorResponse(errors: ErrorResponseData) - - object ErrorResponse { - implicit val encoder: JsonEncoder[ErrorResponse] = DeriveJsonEncoder.gen[ErrorResponse] - - def fromReasons(reasons: String*): ErrorResponse = - new ErrorResponse(ErrorResponseData(Chunk.fromIterable(reasons))) - } - implicit final class RequestOps(private val req: Request) extends AnyVal { def limit: Int = req.url.queryParams.get("limit").flatMap(_.headOption).flatMap(_.toIntOption).getOrElse(10) def offset: Int = req.url.queryParams.get("offset").flatMap(_.headOption).flatMap(_.toIntOption).getOrElse(0) } - } diff --git a/modules/library/src/it/scala/zio/elasticsearch/HttpExecutorSpec.scala b/modules/library/src/it/scala/zio/elasticsearch/HttpExecutorSpec.scala index 7980df71d..76d12eaf9 100644 --- a/modules/library/src/it/scala/zio/elasticsearch/HttpExecutorSpec.scala +++ b/modules/library/src/it/scala/zio/elasticsearch/HttpExecutorSpec.scala @@ -592,6 +592,30 @@ object HttpExecutorSpec extends IntegrationSpec { Executor.execute(ElasticRequest.createIndex(firstSearchIndex)), Executor.execute(ElasticRequest.deleteIndex(firstSearchIndex)).orDie ), + test("search for a document using a match phrase query") { + checkOnce(genDocumentId, genTestDocument, genDocumentId, genTestDocument) { + (firstDocumentId, firstDocument, secondDocumentId, secondDocument) => + for { + _ <- Executor.execute(ElasticRequest.deleteByQuery(firstSearchIndex, matchAll)) + document = firstDocument.copy(stringField = s"this is ${firstDocument.stringField} test") + _ <- + Executor.execute(ElasticRequest.upsert[TestDocument](firstSearchIndex, firstDocumentId, document)) + _ <- Executor.execute( + ElasticRequest + .upsert[TestDocument](firstSearchIndex, secondDocumentId, secondDocument) + .refreshTrue + ) + query = matchPhrase( + field = TestDocument.stringField, + value = firstDocument.stringField + ) + res <- Executor.execute(ElasticRequest.search(firstSearchIndex, query)).documentAs[TestDocument] + } yield assert(res)(Assertion.contains(document)) + } + } @@ around( + Executor.execute(ElasticRequest.createIndex(firstSearchIndex)), + Executor.execute(ElasticRequest.deleteIndex(firstSearchIndex)).orDie + ), test("search for a document using nested query") { checkOnce(genDocumentId, genTestDocument, genDocumentId, genTestDocument) { (firstDocumentId, firstDocument, secondDocumentId, secondDocument) => diff --git a/modules/library/src/main/scala/zio/elasticsearch/ElasticQuery.scala b/modules/library/src/main/scala/zio/elasticsearch/ElasticQuery.scala index e0f1bc7ed..fcd08f16f 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/ElasticQuery.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/ElasticQuery.scala @@ -118,7 +118,7 @@ object ElasticQuery { /** * Constructs a type-safe instance of [[MatchQuery]] using the specified parameters. [[MatchQuery]] is used for - * matching a provided text, number, date or boolean value + * matching a provided text, number, date or boolean value. * * @param field * the [[Field]] object representing the type-safe field for which query is specified for @@ -132,11 +132,11 @@ object ElasticQuery { * an instance of [[MatchQuery]] that represents the match query to be performed. */ final def matches[S, A: ElasticPrimitive](field: Field[S, A], value: A): MatchQuery[S] = - Match(field = field.toString, value = value) + Match(field = field.toString, value = value, boost = None) /** * Constructs an instance of [[MatchQuery]] using the specified parameters. [[MatchQuery]] is used for matching a - * provided text, number, date or boolean value + * provided text, number, date or boolean value. * * @param field * the field for which query is specified for @@ -148,7 +148,37 @@ object ElasticQuery { * an instance of [[MatchQuery]] that represents the match query to be performed. */ final def matches[A: ElasticPrimitive](field: String, value: A): MatchQuery[Any] = - Match(field = field, value = value) + Match(field = field, value = value, boost = None) + + /** + * Constructs a type-safe instance of [[MatchPhraseQuery]] using the specified parameters. [[MatchPhraseQuery]] + * analyzes the text and creates a phrase query out of the analyzed text. + * + * @param field + * the field for which query is specified for + * @param value + * the value to be matched, represented by an instance of type `A` + * @tparam S + * document for which field query is executed + * @return + * an instance of [[MatchPhraseQuery]] that represents the match phrase query to be performed. + */ + final def matchPhrase[S](field: Field[S, String], value: String): MatchPhraseQuery[S] = + MatchPhrase(field = field.toString, value = value, boost = None) + + /** + * Constructs an instance of [[MatchPhraseQuery]] using the specified parameters. [[MatchPhraseQuery]] analyzes the + * text and creates a phrase query out of the analyzed text. + * + * @param field + * the [[Field]] object representing the type-safe field for which query is specified for + * @param value + * the value to be matched, represented by an instance of type `A` + * @return + * an instance of [[MatchPhraseQuery]] that represents the match phrase query to be performed. + */ + final def matchPhrase(field: String, value: String): MatchPhraseQuery[Any] = + MatchPhrase(field = field, value = value, boost = None) /** * Constructs an instance of [[BoolQuery]] with queries that must satisfy the criteria using the specified parameters. 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 fc08d689a..21ee3dbf6 100644 --- a/modules/library/src/main/scala/zio/elasticsearch/query/Queries.scala +++ b/modules/library/src/main/scala/zio/elasticsearch/query/Queries.scala @@ -100,14 +100,20 @@ sealed trait ExistsQuery[S] extends ElasticQuery[S] private[elasticsearch] final case class Exists[S](field: String) extends ExistsQuery[S] { def paramsToJson(fieldPath: Option[String]): Json = - Obj("exists" -> Obj("field" -> (fieldPath.map(_ + ".").getOrElse("") + field).toJson)) + Obj("exists" -> Obj("field" -> fieldPath.foldRight(field)(_ + "." + _).toJson)) } -sealed trait MatchQuery[S] extends ElasticQuery[S] +sealed trait MatchQuery[S] extends ElasticQuery[S] with HasBoost[MatchQuery[S]] -private[elasticsearch] final case class Match[S, A: ElasticPrimitive](field: String, value: A) extends MatchQuery[S] { - def paramsToJson(fieldPath: Option[String]): Json = - Obj("match" -> Obj(fieldPath.map(_ + ".").getOrElse("") + field -> value.toJson)) +private[elasticsearch] final case class Match[S, A: ElasticPrimitive](field: String, value: A, boost: Option[Double]) + extends MatchQuery[S] { self => + def boost(value: Double): MatchQuery[S] = + self.copy(boost = Some(value)) + + def paramsToJson(fieldPath: Option[String]): Json = { + val matchFields = Some(fieldPath.foldRight(field)(_ + "." + _) -> value.toJson) ++ boost.map("boost" -> Num(_)) + Obj("match" -> Obj(matchFields.toList: _*)) + } } sealed trait MatchAllQuery extends ElasticQuery[Any] with HasBoost[MatchAllQuery] @@ -120,6 +126,20 @@ private[elasticsearch] final case class MatchAll(boost: Option[Double]) extends Obj("match_all" -> Obj(boost.map("boost" -> Num(_)).toList: _*)) } +sealed trait MatchPhraseQuery[S] extends ElasticQuery[S] with HasBoost[MatchPhraseQuery[S]] + +private[elasticsearch] final case class MatchPhrase[S](field: String, value: String, boost: Option[Double]) + extends MatchPhraseQuery[S] { self => + def boost(value: Double): MatchPhraseQuery[S] = + self.copy(boost = Some(value)) + + def paramsToJson(fieldPath: Option[String]): Json = { + val matchPhraseFields = + Some(fieldPath.foldRight(field)(_ + "." + _) -> value.toJson) ++ boost.map("boost" -> Num(_)) + Obj("match_phrase" -> Obj(matchPhraseFields.toList: _*)) + } +} + sealed trait NestedQuery[S] extends ElasticQuery[S] with HasIgnoreUnmapped[NestedQuery[S]] @@ -240,7 +260,7 @@ private[elasticsearch] final case class Range[S, A, LB <: LowerBound, UB <: Uppe def paramsToJson(fieldPath: Option[String]): Json = { val rangeFields = Some( - fieldPath.map(_ + ".").getOrElse("") + field -> Obj(List(lower.toJson, upper.toJson).flatten: _*) + fieldPath.foldRight(field)(_ + "." + _) -> Obj(List(lower.toJson, upper.toJson).flatten: _*) ) ++ boost.map("boost" -> Num(_)) Obj("range" -> Obj(rangeFields.toList: _*)) } @@ -274,7 +294,7 @@ private[elasticsearch] final case class Term[S, A: ElasticPrimitive]( val termFields = Some("value" -> value.toJson) ++ boost.map("boost" -> Num(_)) ++ caseInsensitive.map( "case_insensitive" -> Json.Bool(_) ) - Obj("term" -> Obj(fieldPath.map(_ + ".").getOrElse("") + field -> Obj(termFields.toList: _*))) + Obj("term" -> Obj(fieldPath.foldRight(field)(_ + "." + _) -> Obj(termFields.toList: _*))) } } @@ -299,6 +319,6 @@ private[elasticsearch] final case class Wildcard[S]( val wildcardFields = Some("value" -> value.toJson) ++ boost.map("boost" -> Num(_)) ++ caseInsensitive.map( "case_insensitive" -> Json.Bool(_) ) - Obj("wildcard" -> Obj(fieldPath.map(_ + ".").getOrElse("") + field -> Obj(wildcardFields.toList: _*))) + Obj("wildcard" -> Obj(fieldPath.foldRight(field)(_ + "." + _) -> Obj(wildcardFields.toList: _*))) } } diff --git a/modules/library/src/test/scala/zio/elasticsearch/QueryDSLSpec.scala b/modules/library/src/test/scala/zio/elasticsearch/QueryDSLSpec.scala index 4b0f70c6c..31fcc0281 100644 --- a/modules/library/src/test/scala/zio/elasticsearch/QueryDSLSpec.scala +++ b/modules/library/src/test/scala/zio/elasticsearch/QueryDSLSpec.scala @@ -36,21 +36,25 @@ object QueryDSLSpec extends ZIOSpecDefault { val queryBool = matches(field = "day_of_week", value = true) val queryLong = matches(field = "day_of_week", value = 1L) - assert(queryString)(equalTo(Match[Any, String](field = "day_of_week", value = "Monday"))) && - assert(queryBool)(equalTo(Match[Any, Boolean](field = "day_of_week", value = true))) && - assert(queryLong)(equalTo(Match[Any, Long](field = "day_of_week", value = 1))) + assert(queryString)(equalTo(Match[Any, String](field = "day_of_week", value = "Monday", boost = None))) && + assert(queryBool)(equalTo(Match[Any, Boolean](field = "day_of_week", value = true, boost = None))) && + assert(queryLong)(equalTo(Match[Any, Long](field = "day_of_week", value = 1, boost = None))) }, test("successfully create type-safe Match query using `matches` method") { val queryString = matches(field = TestSubDocument.stringField, value = "StringField") val queryInt = matches(field = TestSubDocument.intField, value = 39) - assert(queryString)(equalTo(Match[TestSubDocument, String](field = "stringField", value = "StringField"))) && - assert(queryInt)(equalTo(Match[TestSubDocument, Int](field = "intField", value = 39))) + assert(queryString)( + equalTo(Match[TestSubDocument, String](field = "stringField", value = "StringField", boost = None)) + ) && + assert(queryInt)(equalTo(Match[TestSubDocument, Int](field = "intField", value = 39, boost = None))) }, test("successfully create type-safe Match query with suffix using `matches` method") { val query = matches(field = TestSubDocument.stringField.keyword, value = "StringField") - assert(query)(equalTo(Match[TestSubDocument, String](field = "stringField.keyword", value = "StringField"))) + assert(query)( + equalTo(Match[TestSubDocument, String](field = "stringField.keyword", value = "StringField", boost = None)) + ) }, test("successfully create `Filter` query from two Match queries") { val query = filter( @@ -62,8 +66,8 @@ object QueryDSLSpec extends ZIOSpecDefault { equalTo( Bool[TestDocument]( filter = List( - Match(field = "stringField", value = "StringField"), - Match(field = "customer_gender", value = "MALE") + Match(field = "stringField", value = "StringField", boost = None), + Match(field = "customer_gender", value = "MALE", boost = None) ), must = Nil, mustNot = Nil, @@ -83,8 +87,8 @@ object QueryDSLSpec extends ZIOSpecDefault { equalTo( Bool[TestDocument]( filter = List( - Match(field = "stringField", value = "StringField"), - Match(field = "customer_gender", value = "MALE") + Match(field = "stringField", value = "StringField", boost = None), + Match(field = "customer_gender", value = "MALE", boost = None) ), must = Nil, mustNot = Nil, @@ -106,8 +110,8 @@ object QueryDSLSpec extends ZIOSpecDefault { Bool[TestDocument]( filter = Nil, must = List( - Match(field = "stringField", value = "StringField"), - Match(field = "customer_gender", value = "MALE") + Match(field = "stringField", value = "StringField", boost = None), + Match(field = "customer_gender", value = "MALE", boost = None) ), mustNot = Nil, should = Nil, @@ -129,8 +133,8 @@ object QueryDSLSpec extends ZIOSpecDefault { filter = Nil, must = Nil, mustNot = List( - Match(field = "stringField", value = "StringField"), - Match(field = "customer_gender", value = "MALE") + Match(field = "stringField", value = "StringField", boost = None), + Match(field = "customer_gender", value = "MALE", boost = None) ), should = Nil, boost = None @@ -151,8 +155,8 @@ object QueryDSLSpec extends ZIOSpecDefault { must = Nil, mustNot = Nil, should = List( - Match(field = "stringField", value = "StringField"), - Match(field = "customer_gender", value = "MALE") + Match(field = "stringField", value = "StringField", boost = None), + Match(field = "customer_gender", value = "MALE", boost = None) ), boost = None ) @@ -172,12 +176,12 @@ object QueryDSLSpec extends ZIOSpecDefault { equalTo( Bool[TestDocument]( filter = List( - Match(field = "stringField", value = "StringField"), - Match(field = "customer_gender", value = "MALE") + Match(field = "stringField", value = "StringField", boost = None), + Match(field = "customer_gender", value = "MALE", boost = None) ), - must = List(Match(field = "customer_age", value = 23)), - mustNot = List(Match(field = "intField", value = 17)), - should = List(Match(field = "customer_id", value = 1)), + must = List(Match(field = "customer_age", value = 23, boost = None)), + mustNot = List(Match(field = "intField", value = 17, boost = None)), + should = List(Match(field = "customer_id", value = 1, boost = None)), boost = None ) ) @@ -195,13 +199,13 @@ object QueryDSLSpec extends ZIOSpecDefault { assert(query)( equalTo( Bool[TestDocument]( - filter = List(Match(field = "intField", value = 1)), + filter = List(Match(field = "intField", value = 1, boost = None)), must = List( - Match(field = "stringField", value = "StringField1"), - Match(field = "stringField", value = "StringField2") + Match(field = "stringField", value = "StringField1", boost = None), + Match(field = "stringField", value = "StringField2", boost = None) ), - mustNot = List(Match(field = "intField", value = 17)), - should = List(Match(field = "doubleField", value = 23.0)), + mustNot = List(Match(field = "intField", value = 17, boost = None)), + should = List(Match(field = "doubleField", value = 23.0, boost = None)), boost = None ) ) @@ -219,13 +223,13 @@ object QueryDSLSpec extends ZIOSpecDefault { assert(query)( equalTo( Bool[TestDocument]( - filter = List(Match(field = "stringField", value = "StringField")), - must = List(Match(field = "intField", value = 17)), + filter = List(Match(field = "stringField", value = "StringField", boost = None)), + must = List(Match(field = "intField", value = 17, boost = None)), mustNot = List( - Match(field = "day_of_week", value = "Monday"), - Match(field = "customer_gender", value = "MALE") + Match(field = "day_of_week", value = "Monday", boost = None), + Match(field = "customer_gender", value = "MALE", boost = None) ), - should = List(Match(field = "intField", value = 23)), + should = List(Match(field = "intField", value = 23, boost = None)), boost = None ) ) @@ -243,12 +247,12 @@ object QueryDSLSpec extends ZIOSpecDefault { assert(query)( equalTo( Bool[TestDocument]( - filter = List(Match(field = "stringField", value = "StringField")), - must = List(Match(field = "intField", value = 23)), - mustNot = List(Match(field = "day_of_month", value = 17)), + filter = List(Match(field = "stringField", value = "StringField", boost = None)), + must = List(Match(field = "intField", value = 23, boost = None)), + mustNot = List(Match(field = "day_of_month", value = 17, boost = None)), should = List( - Match(field = "day_of_week", value = "Monday"), - Match(field = "customer_gender", value = "MALE") + Match(field = "day_of_week", value = "Monday", boost = None), + Match(field = "customer_gender", value = "MALE", boost = None) ), boost = None ) @@ -265,10 +269,10 @@ object QueryDSLSpec extends ZIOSpecDefault { assert(query)( equalTo( Bool[TestDocument]( - filter = List(Match(field = "intField", value = 1)), - must = List(Match(field = "doubleField", value = 23.0)), - mustNot = List(Match(field = "intField", value = 17)), - should = List(Match(field = "stringField", value = "StringField")), + filter = List(Match(field = "intField", value = 1, boost = None)), + must = List(Match(field = "doubleField", value = 23.0, boost = None)), + mustNot = List(Match(field = "intField", value = 17, boost = None)), + should = List(Match(field = "stringField", value = "StringField", boost = None)), boost = Some(1.0) ) ) @@ -1025,6 +1029,89 @@ object QueryDSLSpec extends ZIOSpecDefault { assert(query.toJson)(equalTo(expected.toJson)) }, + test("successfully construct MatchPhrase query") { + val querySimple = matchPhrase(field = "stringField", value = "this is a test") + val queryRaw = matchPhrase(field = "stringField.raw", value = "this is a test") + val queryWithBoost = matchPhrase(field = "stringField", value = "this is a test").boost(21.15) + val querySimpleTs = matchPhrase(field = TestDocument.stringField, value = "this is a test") + val queryRawTs = matchPhrase(field = TestDocument.stringField.raw, value = "this is a test") + val queryWithBoostTs = matchPhrase(field = TestDocument.stringField, value = "this is a test").boost(21.15) + + assert(querySimple)( + equalTo(MatchPhrase[Any](field = "stringField", value = "this is a test", boost = None)) + ) && assert(querySimpleTs)( + equalTo(MatchPhrase[TestDocument](field = "stringField", value = "this is a test", boost = None)) + ) && assert(queryRaw)( + equalTo(MatchPhrase[Any](field = "stringField.raw", value = "this is a test", boost = None)) + ) && assert(queryRawTs)( + equalTo(MatchPhrase[TestDocument](field = "stringField.raw", value = "this is a test", boost = None)) + ) && assert(queryWithBoost)( + equalTo(MatchPhrase[Any](field = "stringField", value = "this is a test", boost = Some(21.15))) + ) && assert(queryWithBoostTs)( + equalTo(MatchPhrase[TestDocument](field = "stringField", value = "this is a test", boost = Some(21.15))) + ) + }, + test("successfully encode MatchPhrase query") { + val querySimple = matchPhrase(field = "stringField", value = "this is a test") + val queryRaw = matchPhrase(field = "stringField.raw", value = "this is a test") + val queryWithBoost = matchPhrase(field = "stringField", value = "this is a test").boost(21.15) + val querySimpleTs = matchPhrase(field = TestDocument.stringField, value = "this is a test") + val queryRawTs = matchPhrase(field = TestDocument.stringField.raw, value = "this is a test") + val queryWithBoostTs = matchPhrase(field = TestDocument.stringField, value = "this is a test").boost(21.15) + + val querySimpleExpectedJson = + """ + |{ + | "query": { + | "match_phrase": { + | "stringField": "this is a test" + | } + | } + |} + |""".stripMargin + + val queryRawExpectedJson = + """ + |{ + | "query": { + | "match_phrase": { + | "stringField.raw": "this is a test" + | } + | } + |} + |""".stripMargin + + val queryWithBoostExpectedJson = + """ + |{ + | "query": { + | "match_phrase": { + | "stringField": "this is a test", + | "boost": 21.15 + | } + | } + |} + |""".stripMargin + + assert(querySimple.toJson)(equalTo(querySimpleExpectedJson.toJson)) && assert(querySimpleTs.toJson)( + equalTo(querySimpleExpectedJson.toJson) + ) && + assert(queryRaw.toJson)(equalTo(queryRawExpectedJson.toJson)) && assert(queryRawTs.toJson)( + equalTo(queryRawExpectedJson.toJson) + ) && + assert(queryWithBoost.toJson)(equalTo(queryWithBoostExpectedJson.toJson)) && assert(queryWithBoostTs.toJson)( + equalTo(queryWithBoostExpectedJson.toJson) + ) + }, + test("successfully create type-safe Match query using `matches` method") { + val queryString = matches(field = TestSubDocument.stringField, value = "StringField") + val queryInt = matches(field = TestSubDocument.intField, value = 39) + + assert(queryString)( + equalTo(Match[TestSubDocument, String](field = "stringField", value = "StringField", boost = None)) + ) && + assert(queryInt)(equalTo(Match[TestSubDocument, Int](field = "intField", value = 39, boost = None))) + }, test("properly encode Nested Query with MatchAll Query") { val query = nested(path = "customer", query = matchAll) val expected = diff --git a/website/sidebars.js b/website/sidebars.js index 9a91761dd..0724558b6 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -19,6 +19,7 @@ module.exports = { 'overview/queries/elastic_query_filter', 'overview/queries/elastic_query_match_all', 'overview/queries/elastic_query_matches', + 'overview/queries/elastic_query_match_phrase', 'overview/queries/elastic_query_must', 'overview/queries/elastic_query_must_not', 'overview/queries/elastic_query_nested',