From 8b07b258847c902a2820fb286127b4aebb90679b Mon Sep 17 00:00:00 2001 From: cdmbr Date: Mon, 17 Feb 2025 09:48:10 -0300 Subject: [PATCH] feat: adds boost support into interval queries --- .../queries/IntervalsQueryBuilderFnTest.scala | 54 +++++++++++++++++++ .../searches/queries/IntervalsQuery.scala | 2 +- .../queries/IntervalsQueryBuilderFn.scala | 8 ++- 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/elastic4s-core/src/test/scala/com/sksamuel/elastic4s/requests/searches/queries/IntervalsQueryBuilderFnTest.scala b/elastic4s-core/src/test/scala/com/sksamuel/elastic4s/requests/searches/queries/IntervalsQueryBuilderFnTest.scala index 21ea4c9005..881376c51b 100644 --- a/elastic4s-core/src/test/scala/com/sksamuel/elastic4s/requests/searches/queries/IntervalsQueryBuilderFnTest.scala +++ b/elastic4s-core/src/test/scala/com/sksamuel/elastic4s/requests/searches/queries/IntervalsQueryBuilderFnTest.scala @@ -188,4 +188,58 @@ class IntervalsQueryBuilderFnTest extends AnyFunSuite with Matchers with GivenWh Then("query should have right fields") queryBody.string should matchJson(expected) } + + test("Should correctly build intervals boosted query") { + Given("An intervals query with boost set") + val query = IntervalsQuery( + "my_text", + AllOf(List( + Match(query = "my favorite food").maxGaps(0).ordered(true), + AnyOf(intervals = + List( + Match(query = "hot water"), + Match(query = "cold porridge") + ) + ) + )).ordered(true), + Some(2.5D) + ) + + When("Intervals query is built") + val queryBody = IntervalsQueryBuilderFn(query) + + Then("query should have right fields and boost set") + queryBody.string should matchJson(intervalsBoostedQuery) + } + + def intervalsBoostedQuery: String = + """ + |{ + | "intervals" : { + | "my_text" : { + | "boost": 2.5, + | "all_of" : { + | "ordered" : true, + | "intervals" : [ + | { + | "match" : { + | "query" : "my favorite food", + | "max_gaps" : 0, + | "ordered" : true + | } + | }, + | { + | "any_of" : { + | "intervals" : [ + | { "match" : { "query" : "hot water" } }, + | { "match" : { "query" : "cold porridge" } } + | ] + | } + | } + | ] + | } + | } + | } + |} + """.stripMargin.replace("\n", "") } diff --git a/elastic4s-domain/src/main/scala/com/sksamuel/elastic4s/requests/searches/queries/IntervalsQuery.scala b/elastic4s-domain/src/main/scala/com/sksamuel/elastic4s/requests/searches/queries/IntervalsQuery.scala index bea4cd1db0..fb966b7bd5 100644 --- a/elastic4s-domain/src/main/scala/com/sksamuel/elastic4s/requests/searches/queries/IntervalsQuery.scala +++ b/elastic4s-domain/src/main/scala/com/sksamuel/elastic4s/requests/searches/queries/IntervalsQuery.scala @@ -3,7 +3,7 @@ package com.sksamuel.elastic4s.requests.searches.queries import com.sksamuel.elastic4s.requests.script.Script import com.sksamuel.elastic4s.ext.OptionImplicits._ -case class IntervalsQuery(field: String, rule: IntervalsRule) extends Query +case class IntervalsQuery(field: String, rule: IntervalsRule, boost: Option[Double] = None) extends Query sealed trait IntervalsRule case class Match( diff --git a/elastic4s-handlers/src/main/scala/com/sksamuel/elastic4s/handlers/searches/queries/IntervalsQueryBuilderFn.scala b/elastic4s-handlers/src/main/scala/com/sksamuel/elastic4s/handlers/searches/queries/IntervalsQueryBuilderFn.scala index c47ac28f7d..110e5a0ff5 100644 --- a/elastic4s-handlers/src/main/scala/com/sksamuel/elastic4s/handlers/searches/queries/IntervalsQueryBuilderFn.scala +++ b/elastic4s-handlers/src/main/scala/com/sksamuel/elastic4s/handlers/searches/queries/IntervalsQueryBuilderFn.scala @@ -143,7 +143,13 @@ object IntervalsQueryBuilderFn { def apply(q: IntervalsQuery): XContentBuilder = { val builder = XContentFactory.jsonBuilder() builder.startObject("intervals") - builder.rawField(q.field, IntervalsRuleBuilderFn(q.rule)) + builder.rawField( + q.field, { + val ruleBuilder = IntervalsRuleBuilderFn(q.rule) + q.boost.foreach(ruleBuilder.field("boost", _)) + ruleBuilder + } + ) builder.endObject() } }