Skip to content

Commit 72e782b

Browse files
committed
Move ElasticInterval object in separated file, fix some problems.
1 parent b14e4d9 commit 72e782b

File tree

5 files changed

+127
-143
lines changed

5 files changed

+127
-143
lines changed

docs/overview/queries/elastic_query_interval.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ val queryWithMaxGaps: IntervalQuery[Document] =
3737
If you want to specify the word order requirement, use the `orderedOn` method:
3838
```scala
3939
val queryWithOrder: IntervalQuery[Document] =
40-
intervals(field = "content", rule = intervalMatch("targetWord").orderedOn())
40+
intervals(field = "content", rule = intervalMatch("targetWord").orderedOn)
4141
```
4242

4343
You can also apply additional filters to the query:
@@ -53,7 +53,7 @@ val queryManually: IntervalQuery[Document] =
5353
field = "content",
5454
rule = intervalMatch("targetWord")
5555
.maxGaps(2)
56-
.orderedOn()
56+
.orderedOn
5757
.filter(IntervalFilter.someFilter)
5858
.analyzer("standard")
5959
)

modules/integration/src/test/scala/zio/elasticsearch/HttpExecutorSpec.scala

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ package zio.elasticsearch
1919
import zio.Chunk
2020
import zio.elasticsearch.ElasticAggregation._
2121
import zio.elasticsearch.ElasticHighlight.highlight
22+
import zio.elasticsearch.ElasticIntervalQuery.intervalMatch
2223
import zio.elasticsearch.ElasticQuery.{contains => _, _}
2324
import zio.elasticsearch.ElasticSort.sortBy
2425
import zio.elasticsearch.aggregation.AggregationOrder
2526
import zio.elasticsearch.data.GeoPoint
2627
import zio.elasticsearch.domain.{PartialTestDocument, TestDocument, TestSubDocument}
2728
import zio.elasticsearch.executor.Executor
2829
import zio.elasticsearch.query.DistanceUnit.Kilometers
29-
import zio.elasticsearch.query.ElasticIntervalQuery.intervalMatch
3030
import zio.elasticsearch.query.FunctionScoreFunction.randomScoreFunction
3131
import zio.elasticsearch.query.MultiMatchType._
3232
import zio.elasticsearch.query.sort.SortMode.Max
@@ -2774,24 +2774,16 @@ object HttpExecutorSpec extends IntegrationSpec {
27742774
),
27752775
suite("intervals query")(
27762776
test("intervalMatch returns only matching document") {
2777-
checkOnce(genDocumentId, genTestDocument, Gen.alphaNumericString, genDocumentId, genTestDocument) {
2778-
(idMatch, docMatch, targetWord, idNoMatch, docNoMatch) =>
2779-
val docShouldMatch = docMatch.copy(stringField = s"prefix $targetWord suffix")
2780-
val docShouldNotMatch = docNoMatch.copy(stringField = "completely unrelated text")
2781-
val field = TestDocument.stringField.toString
2782-
val query = intervals(field, intervalMatch(targetWord))
2777+
checkOnce(genDocumentId, genTestDocument, Gen.alphaNumericString.filter(_.nonEmpty)) {
2778+
(idMatch, docMatch, targetWord) =>
2779+
val docShouldMatch = docMatch.copy(stringField = s"prefix $targetWord suffix")
2780+
val query = intervals(TestDocument.stringField, intervalMatch(targetWord))
27832781

27842782
for {
2785-
_ <- Executor.execute(ElasticRequest.deleteByQuery(firstSearchIndex, matchAll))
2786-
_ <- Executor.execute(ElasticRequest.upsert(firstSearchIndex, idMatch, docShouldMatch))
2787-
_ <- Executor.execute(
2788-
ElasticRequest.upsert(firstSearchIndex, idNoMatch, docShouldNotMatch).refreshTrue
2789-
)
2783+
_ <- Executor.execute(ElasticRequest.deleteByQuery(firstSearchIndex, matchAll))
2784+
_ <- Executor.execute(ElasticRequest.upsert(firstSearchIndex, idMatch, docShouldMatch).refreshTrue)
27902785
res <- Executor.execute(ElasticRequest.search(firstSearchIndex, query)).documentAs[TestDocument]
2791-
} yield assert(res)(
2792-
Assertion.contains(docShouldMatch) &&
2793-
Assertion.not(Assertion.contains(docShouldNotMatch))
2794-
)
2786+
} yield assert(res)(Assertion.hasSameElements(Chunk(docShouldMatch)))
27952787
}
27962788
} @@ around(
27972789
Executor.execute(ElasticRequest.createIndex(firstSearchIndex)),
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package zio.elasticsearch
2+
3+
import zio.NonEmptyChunk
4+
import zio.elasticsearch.query.{
5+
IntervalAllOf,
6+
IntervalAnyOf,
7+
IntervalFilter,
8+
IntervalFuzzy,
9+
IntervalMatch,
10+
IntervalPrefix,
11+
IntervalRange,
12+
IntervalRegexp,
13+
IntervalRule,
14+
IntervalWildcard,
15+
Regexp
16+
}
17+
import zio.json.ast.Json
18+
19+
object ElasticIntervalQuery {
20+
21+
def intervalAllOf[S](intervals: NonEmptyChunk[IntervalRule]): IntervalAllOf[S] =
22+
IntervalAllOf(intervals = intervals, maxGaps = None, ordered = None, filter = None)
23+
24+
def intervalAnyOf[S](intervals: NonEmptyChunk[IntervalRule]): IntervalAnyOf[S] =
25+
IntervalAnyOf(intervals = intervals, filter = None)
26+
27+
def intervalContains[S](pattern: String): IntervalWildcard[S] =
28+
IntervalWildcard(s"*$pattern*", analyzer = None, useField = None)
29+
30+
def intervalEndsWith[S](pattern: String): IntervalWildcard[S] =
31+
IntervalWildcard(s"*$pattern", analyzer = None, useField = None)
32+
33+
def intervalFilter[S](
34+
after: Option[IntervalRule] = None,
35+
before: Option[IntervalRule] = None,
36+
containedBy: Option[IntervalRule] = None,
37+
containing: Option[IntervalRule] = None,
38+
notContainedBy: Option[IntervalRule] = None,
39+
notContaining: Option[IntervalRule] = None,
40+
notOverlapping: Option[IntervalRule] = None,
41+
overlapping: Option[IntervalRule] = None,
42+
script: Option[Json] = None
43+
): Option[IntervalFilter[S]] = {
44+
45+
val filter: IntervalFilter[S] = IntervalFilter(
46+
after = after,
47+
before = before,
48+
containedBy = containedBy,
49+
containing = containing,
50+
notContainedBy = notContainedBy,
51+
notContaining = notContaining,
52+
notOverlapping = notOverlapping,
53+
overlapping = overlapping,
54+
script = script
55+
)
56+
57+
Some(filter).filterNot(_ =>
58+
List(after, before, containedBy, containing, notContainedBy, notContaining, notOverlapping, overlapping, script)
59+
.forall(_.isEmpty)
60+
)
61+
}
62+
63+
def intervalFuzzy[S](term: String): IntervalFuzzy[S] =
64+
IntervalFuzzy(
65+
term = term,
66+
prefixLength = None,
67+
transpositions = None,
68+
fuzziness = None,
69+
analyzer = None,
70+
useField = None
71+
)
72+
73+
def intervalMatch[S](query: String): IntervalMatch[S] =
74+
IntervalMatch(query = query, analyzer = None, useField = None, maxGaps = None, ordered = None, filter = None)
75+
76+
def intervalPrefix[S](prefix: String): IntervalPrefix[S] =
77+
IntervalPrefix(prefix = prefix, analyzer = None, useField = None)
78+
79+
def intervalRange[S](
80+
lower: Option[IntervalRule] = None,
81+
upper: Option[IntervalRule] = None,
82+
analyzer: Option[String] = None,
83+
useField: Option[String] = None
84+
): IntervalRange[S] =
85+
IntervalRange(lower = lower, upper = upper, analyzer = analyzer, useField = useField)
86+
87+
def intervalRegexp[S](pattern: Regexp[S]): IntervalRegexp[S] =
88+
IntervalRegexp(pattern = pattern, analyzer = None, useField = None)
89+
90+
def intervalStartsWith[S](pattern: String): IntervalWildcard[S] =
91+
IntervalWildcard(s"$pattern*", analyzer = None, useField = None)
92+
93+
def intervalWildcard[S](pattern: String): IntervalWildcard[S] =
94+
IntervalWildcard(pattern = pattern, analyzer = None, useField = None)
95+
}

modules/library/src/main/scala/zio/elasticsearch/query/ElasticIntervalRule.scala

Lines changed: 19 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import zio.elasticsearch.Field
2121
import zio.elasticsearch.query.options.{HasAnalyzer, HasUseField}
2222
import zio.json.ast.Json
2323
import zio.json.ast.Json.{Arr, Obj, Str}
24-
import zio.{Chunk, NonEmptyChunk}
24+
import zio.Chunk
2525

2626
private[elasticsearch] sealed trait BoundType
2727
private[elasticsearch] sealed trait Inclusive extends BoundType
@@ -138,9 +138,9 @@ private[elasticsearch] final case class IntervalFuzzy[S](
138138

139139
def analyzer(value: String): IntervalFuzzy[S] = copy(analyzer = Some(value))
140140

141-
def useField(field: Field[_, _]): IntervalFuzzy[S] = copy(useField = Some(field.toString))
141+
def useField(field: Field[_, _]): IntervalFuzzy[S] = copy(useField = Some(field.name))
142142

143-
def useField(field: String): IntervalFuzzy[S] = copy(useField = Some(Field(None, field).toString))
143+
def useField(field: String): IntervalFuzzy[S] = copy(useField = Some(field))
144144

145145
def prefixLength(length: Int): IntervalFuzzy[S] = copy(prefixLength = Some(length))
146146

@@ -184,9 +184,9 @@ private[elasticsearch] final case class IntervalMatch[S](
184184

185185
def orderedOff: IntervalMatch[S] = copy(ordered = Some(false))
186186

187-
def useField(field: Field[_, _]): IntervalMatch[S] = copy(useField = Some(field.toString))
187+
def useField(field: Field[_, _]): IntervalMatch[S] = copy(useField = Some(field.name))
188188

189-
def useField(field: String): IntervalMatch[S] = copy(useField = Some(Field(None, field).toString))
189+
def useField(field: String): IntervalMatch[S] = copy(useField = Some(field))
190190

191191
override private[elasticsearch] def toJson: Json =
192192
Obj(
@@ -213,9 +213,9 @@ private[elasticsearch] final case class IntervalPrefix[S](
213213

214214
def analyzer(value: String): IntervalPrefix[S] = copy(analyzer = Some(value))
215215

216-
def useField(field: Field[_, _]): IntervalPrefix[S] = copy(useField = Some(field.toString))
216+
def useField(field: Field[_, _]): IntervalPrefix[S] = copy(useField = Some(field.name))
217217

218-
def useField(field: String): IntervalPrefix[S] = copy(useField = Some(Field(None, field).toString))
218+
def useField(field: String): IntervalPrefix[S] = copy(useField = Some(field))
219219

220220
override private[elasticsearch] def toJson: Json =
221221
Obj(
@@ -240,25 +240,21 @@ private[elasticsearch] final case class IntervalRange[S](
240240

241241
def analyzer(value: String): IntervalRange[S] = copy(analyzer = Some(value))
242242

243-
def lower[B <: BoundType](b: Bound[B]): IntervalRange[S] = copy(lower = Some(GreaterThanInterval(b.value)))
243+
def gt[B <: BoundType](value: String): IntervalRange[S] = copy(lower = Some(GreaterThanInterval(value)))
244244

245-
def upper[B <: BoundType](b: Bound[B]): IntervalRange[S] = copy(upper = Some(LessThanInterval(b.value)))
245+
def gte[B <: BoundType](value: String): IntervalRange[S] = copy(lower = Some(GreaterThanOrEqualToInterval(value)))
246246

247-
def useField(field: Field[_, _]): IntervalRange[S] = copy(useField = Some(field.toString))
247+
def lower[B <: BoundType](b: Bound[B]): IntervalRange[S] = copy(lower = Some(GreaterThanInterval(b.value)))
248248

249-
def useField(field: String): IntervalRange[S] = copy(useField = Some(Field(None, field).toString))
249+
def lt[B <: BoundType](value: String): IntervalRange[S] = copy(upper = Some(LessThanInterval(value)))
250250

251-
def gte[B <: BoundType](value: String): IntervalRange[S] =
252-
copy(lower = Some(GreaterThanOrEqualToInterval(value)))
251+
def lte[B <: BoundType](value: String): IntervalRange[S] = copy(upper = Some(LessThanOrEqualToInterval(value)))
253252

254-
def gt[B <: BoundType](value: String): IntervalRange[S] =
255-
copy(lower = Some(GreaterThanInterval(value)))
253+
def upper[B <: BoundType](b: Bound[B]): IntervalRange[S] = copy(upper = Some(LessThanInterval(b.value)))
256254

257-
def lte[B <: BoundType](value: String): IntervalRange[S] =
258-
copy(upper = Some(LessThanOrEqualToInterval(value)))
255+
def useField(field: Field[_, _]): IntervalRange[S] = copy(useField = Some(field.name))
259256

260-
def lt[B <: BoundType](value: String): IntervalRange[S] =
261-
copy(upper = Some(LessThanInterval(value)))
257+
def useField(field: String): IntervalRange[S] = copy(useField = Some(field))
262258

263259
private[elasticsearch] def toJson: Json =
264260
Obj(
@@ -283,9 +279,9 @@ private[elasticsearch] final case class IntervalRegexp[S](
283279

284280
def analyzer(value: String): IntervalRegexp[S] = copy(analyzer = Some(value))
285281

286-
def useField(field: Field[_, _]): IntervalRegexp[S] = copy(useField = Some(field.toString))
282+
def useField(field: Field[_, _]): IntervalRegexp[S] = copy(useField = Some(field.name))
287283

288-
def useField(field: String): IntervalRegexp[S] = copy(useField = Some(Field(None, field).toString))
284+
def useField(field: String): IntervalRegexp[S] = copy(useField = Some(field))
289285

290286
private[elasticsearch] def toJson: Json =
291287
Obj(
@@ -309,9 +305,9 @@ private[elasticsearch] final case class IntervalWildcard[S](
309305

310306
def analyzer(value: String): IntervalWildcard[S] = copy(analyzer = Some(value))
311307

312-
def useField(field: Field[_, _]): IntervalWildcard[S] = copy(useField = Some(field.toString))
308+
def useField(field: Field[_, _]): IntervalWildcard[S] = copy(useField = Some(field.name))
313309

314-
def useField(field: String): IntervalWildcard[S] = copy(useField = Some(Field(None, field).toString))
310+
def useField(field: String): IntervalWildcard[S] = copy(useField = Some(field))
315311

316312
private[elasticsearch] def toJson: Json =
317313
Obj(
@@ -324,81 +320,3 @@ private[elasticsearch] final case class IntervalWildcard[S](
324320
)
325321
)
326322
}
327-
328-
object ElasticIntervalQuery {
329-
330-
def intervalAllOf[S](intervals: NonEmptyChunk[IntervalRule]): IntervalAllOf[S] =
331-
IntervalAllOf(intervals = intervals, maxGaps = None, ordered = None, filter = None)
332-
333-
def intervalAnyOf[S](intervals: NonEmptyChunk[IntervalRule]): IntervalAnyOf[S] =
334-
IntervalAnyOf(intervals = intervals, filter = None)
335-
336-
def intervalContains[S](pattern: String): IntervalWildcard[S] =
337-
IntervalWildcard(s"*$pattern*", analyzer = None, useField = None)
338-
339-
def intervalEndsWith[S](pattern: String): IntervalWildcard[S] =
340-
IntervalWildcard(s"*$pattern", analyzer = None, useField = None)
341-
342-
def intervalFilter[S](
343-
after: Option[IntervalRule] = None,
344-
before: Option[IntervalRule] = None,
345-
containedBy: Option[IntervalRule] = None,
346-
containing: Option[IntervalRule] = None,
347-
notContainedBy: Option[IntervalRule] = None,
348-
notContaining: Option[IntervalRule] = None,
349-
notOverlapping: Option[IntervalRule] = None,
350-
overlapping: Option[IntervalRule] = None,
351-
script: Option[Json] = None
352-
): Option[IntervalFilter[S]] = {
353-
354-
val filter: IntervalFilter[S] = IntervalFilter(
355-
after = after,
356-
before = before,
357-
containedBy = containedBy,
358-
containing = containing,
359-
notContainedBy = notContainedBy,
360-
notContaining = notContaining,
361-
notOverlapping = notOverlapping,
362-
overlapping = overlapping,
363-
script = script
364-
)
365-
366-
Some(filter).filterNot(_ =>
367-
List(after, before, containedBy, containing, notContainedBy, notContaining, notOverlapping, overlapping, script)
368-
.forall(_.isEmpty)
369-
)
370-
}
371-
372-
def intervalFuzzy[S](term: String): IntervalFuzzy[S] =
373-
IntervalFuzzy(
374-
term = term,
375-
prefixLength = None,
376-
transpositions = None,
377-
fuzziness = None,
378-
analyzer = None,
379-
useField = None
380-
)
381-
382-
def intervalMatch[S](query: String): IntervalMatch[S] =
383-
IntervalMatch(query = query, analyzer = None, useField = None, maxGaps = None, ordered = None, filter = None)
384-
385-
def intervalPrefix[S](prefix: String): IntervalPrefix[S] =
386-
IntervalPrefix(prefix = prefix, analyzer = None, useField = None)
387-
388-
def intervalRange[S](
389-
lower: Option[IntervalRule] = None,
390-
upper: Option[IntervalRule] = None,
391-
analyzer: Option[String] = None,
392-
useField: Option[String] = None
393-
): IntervalRange[S] =
394-
IntervalRange(lower = lower, upper = upper, analyzer = analyzer, useField = useField)
395-
396-
def intervalRegexp[S](pattern: Regexp[S]): IntervalRegexp[S] =
397-
IntervalRegexp(pattern = pattern, analyzer = None, useField = None)
398-
399-
def intervalStartsWith[S](pattern: String): IntervalWildcard[S] =
400-
IntervalWildcard(s"$pattern*", analyzer = None, useField = None)
401-
402-
def intervalWildcard[S](pattern: String): IntervalWildcard[S] =
403-
IntervalWildcard(pattern = pattern, analyzer = None, useField = None)
404-
}

0 commit comments

Comments
 (0)