-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(dsl): Support geoPolygon
query
#264
Changes from 6 commits
75d3dd4
2aa0dca
8d3d807
5adaefc
c20d077
39bc4ca
5565098
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
--- | ||
id: elastic_query_geo_polygon | ||
title: "Geo-polygon Query" | ||
--- | ||
|
||
A query returning hits that only fall within a polygon of points. | ||
|
||
In order to use the `GeoPolygon` query import the following: | ||
```scala | ||
import zio.elasticsearch.query.GeoPolygonQuery | ||
import zio.elasticsearch.ElasticQuery._ | ||
``` | ||
|
||
You can create a `GeoPolygon` query using the `geoPolygon` method with list of coordinates in the following manner: | ||
```scala | ||
val query: GeoPolygonQuery = geoPolygon(field = "location", List("0, 0", "0, 90", "90, 90", "90, 0")) | ||
``` | ||
|
||
You can create a [type-safe](https://lambdaworks.github.io/zio-elasticsearch/overview/overview_zio_prelude_schema) `GeoPolygon` query using the `geoPolygon` method with list of coordinates in the following manner: | ||
```scala | ||
val query: GeoPolygonQuery = geoPolygon(field = Document.location, List("0, 0", "0, 90", "90, 90", "90, 0")) | ||
``` | ||
|
||
|
||
If you want to change the `_name`, you can use `name` method: | ||
```scala | ||
val queryWithName: GeoPolygonQuery = geoPolygon(field = "location", coordinates = List("0, 0", "0, 90", "90, 90", "90, 0")).name("name") | ||
``` | ||
|
||
If you want to change the `validation_method`, you can use `validationMethod` method: | ||
```scala | ||
import zio.elasticsearch.query.ValidationMethod | ||
|
||
val queryWithValidationMethod: GeoPolygonQuery = geoPolygon(field = "location", coordinates = List("0, 0", "0, 90", "90, 90", "90, 0")).validationMethod(value = ValidationMethod.IgnoreMalformed) | ||
``` | ||
|
||
You can find more information about `GeoPolygon` query [here](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-geo-polygon-query.html). |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -403,6 +403,46 @@ object ElasticQuery { | |||||
validationMethod = None | ||||||
) | ||||||
|
||||||
/** | ||||||
* Constructs a type-safe instance of [[zio.elasticsearch.query.GeoPolygonQuery]] using the specified parameters. | ||||||
* | ||||||
* @param field | ||||||
* the type-safe field for which query is specified for | ||||||
* @param coordinates | ||||||
* list of longitudes and latitudes of the desired points written as string (e.g. ["40, 31", "25, 31"]) or geo hash | ||||||
* (e.g. ["drm3btev3e86", "drm3btev3e87"] ) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* @tparam S | ||||||
* document for which field query is executed | ||||||
* @return | ||||||
* an instance of [[zio.elasticsearch.query.GeoPolygonQuery]] that represents `geo_polygon` query to be performed. | ||||||
*/ | ||||||
final def geoPolygon[S](field: Field[S, _], coordinates: List[String]): GeoPolygonQuery[S] = | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you replace |
||||||
GeoPolygon( | ||||||
field = field.toString, | ||||||
points = coordinates, | ||||||
queryName = None, | ||||||
validationMethod = None | ||||||
) | ||||||
|
||||||
drmarjanovic marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
/** | ||||||
* Constructs an instance of [[zio.elasticsearch.query.GeoPolygonQuery]] using the specified parameters. | ||||||
* | ||||||
* @param field | ||||||
* the field for which query is specified for | ||||||
* @param coordinates | ||||||
* list of longitudes and latitudes of the desired points written as string (e.g. ["40, 31", "25, 31"]) or geo hash | ||||||
* (e.g. ["drm3btev3e86", "drm3btev3e87"] ) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* @return | ||||||
* an instance of [[zio.elasticsearch.query.GeoPolygonQuery]] that represents `geo_polygon` query to be performed. | ||||||
*/ | ||||||
final def geoPolygon(field: String, coordinates: List[String]): GeoPolygonQuery[Any] = | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you replace |
||||||
GeoPolygon( | ||||||
field = field, | ||||||
points = coordinates, | ||||||
queryName = None, | ||||||
validationMethod = None | ||||||
) | ||||||
|
||||||
/** | ||||||
* Constructs an instance of [[zio.elasticsearch.query.HasChildQuery]] using the specified parameters. | ||||||
* | ||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -534,6 +534,61 @@ private[elasticsearch] final case class GeoDistance[S]( | |||||||||||||
|
||||||||||||||
} | ||||||||||||||
|
||||||||||||||
sealed trait GeoPolygonQuery[S] extends ElasticQuery[S] { | ||||||||||||||
|
||||||||||||||
/** | ||||||||||||||
* Sets the `queryName` parameter for the [[zio.elasticsearch.query.GeoPolygonQuery]]. Represents the optional name | ||||||||||||||
* field to identify the query | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
* | ||||||||||||||
* @param value | ||||||||||||||
* the text value to represent the name field | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
* @return | ||||||||||||||
* an instance of [[zio.elasticsearch.query.GeoPolygonQuery]] enriched with the `queryName` parameter. | ||||||||||||||
*/ | ||||||||||||||
def name(value: String): GeoPolygonQuery[S] | ||||||||||||||
|
||||||||||||||
/** | ||||||||||||||
* Sets the `validationMethod` parameter for the [[zio.elasticsearch.query.GeoPolygonQuery]]. Defines handling of | ||||||||||||||
* incorrect coordinates. | ||||||||||||||
* | ||||||||||||||
* @param value | ||||||||||||||
* defines how to handle invalid latitude nad longitude: | ||||||||||||||
* - [[zio.elasticsearch.query.ValidationMethod.Strict]]: Default method | ||||||||||||||
* - [[zio.elasticsearch.query.ValidationMethod.IgnoreMalformed]]: Accepts geo points with invalid latitude or | ||||||||||||||
* longitude | ||||||||||||||
* - [[zio.elasticsearch.query.ValidationMethod.Coerce]]: Additionally try and infer correct coordinates | ||||||||||||||
* @return | ||||||||||||||
* an instance of [[zio.elasticsearch.query.GeoPolygonQuery]] enriched with the `validationMethod` parameter. | ||||||||||||||
*/ | ||||||||||||||
def validationMethod(value: ValidationMethod): GeoPolygonQuery[S] | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
private[elasticsearch] final case class GeoPolygon[S]( | ||||||||||||||
field: String, | ||||||||||||||
points: List[String], | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you replace |
||||||||||||||
queryName: Option[String], | ||||||||||||||
validationMethod: Option[ValidationMethod] | ||||||||||||||
) extends GeoPolygonQuery[S] { self => | ||||||||||||||
|
||||||||||||||
def name(value: String): GeoPolygonQuery[S] = | ||||||||||||||
self.copy(queryName = Some(value)) | ||||||||||||||
|
||||||||||||||
def validationMethod(value: ValidationMethod): GeoPolygonQuery[S] = | ||||||||||||||
self.copy(validationMethod = Some(value)) | ||||||||||||||
|
||||||||||||||
private[elasticsearch] def toJson(fieldPath: Option[String]): Json = | ||||||||||||||
Obj( | ||||||||||||||
"geo_polygon" -> Obj( | ||||||||||||||
Chunk( | ||||||||||||||
Some(field -> Obj("points" -> Arr(points.map(Json.Str(_)): _*))), | ||||||||||||||
queryName.map("_name" -> _.toJson), | ||||||||||||||
validationMethod.map("validation_method" -> _.toString.toJson) | ||||||||||||||
).flatten: _* | ||||||||||||||
) | ||||||||||||||
) | ||||||||||||||
|
||||||||||||||
} | ||||||||||||||
|
||||||||||||||
sealed trait HasChildQuery[S] | ||||||||||||||
extends ElasticQuery[S] | ||||||||||||||
with HasIgnoreUnmapped[HasChildQuery[S]] | ||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -813,6 +813,68 @@ object ElasticQuerySpec extends ZIOSpecDefault { | |||||
) | ||||||
) | ||||||
}, | ||||||
test("geoPolygon") { | ||||||
val query = | ||||||
geoPolygon("testField", List("40, -70", "30, -80", "20, -90")) | ||||||
val queryString = | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
geoPolygon(TestDocument.stringField, List("drm3btev3e86", "drm3btev3e87")) | ||||||
val queryWithName = | ||||||
geoPolygon(TestDocument.stringField, List("40, -70", "30, -80", "20, -90")).name("name") | ||||||
val queryWithValidationMethod = | ||||||
geoPolygon(TestDocument.stringField, List("40, -70", "30, -80", "20, -90")).validationMethod( | ||||||
IgnoreMalformed | ||||||
) | ||||||
val queryWithAllParams = geoPolygon(TestDocument.stringField, List("40, -70", "30, -80", "20, -90")) | ||||||
.validationMethod(IgnoreMalformed) | ||||||
.name("name") | ||||||
|
||||||
assert(query)( | ||||||
equalTo( | ||||||
GeoPolygon[Any]( | ||||||
field = "testField", | ||||||
points = List("40, -70", "30, -80", "20, -90"), | ||||||
queryName = None, | ||||||
validationMethod = None | ||||||
) | ||||||
) | ||||||
) && assert(queryString)( | ||||||
equalTo( | ||||||
GeoPolygon[TestDocument]( | ||||||
field = "stringField", | ||||||
points = List("drm3btev3e86", "drm3btev3e87"), | ||||||
queryName = None, | ||||||
validationMethod = None | ||||||
) | ||||||
) | ||||||
) && assert(queryWithName)( | ||||||
equalTo( | ||||||
GeoPolygon[TestDocument]( | ||||||
field = "stringField", | ||||||
points = List("40, -70", "30, -80", "20, -90"), | ||||||
queryName = Some("name"), | ||||||
validationMethod = None | ||||||
) | ||||||
) | ||||||
) && assert(queryWithValidationMethod)( | ||||||
equalTo( | ||||||
GeoPolygon[TestDocument]( | ||||||
field = "stringField", | ||||||
points = List("40, -70", "30, -80", "20, -90"), | ||||||
queryName = None, | ||||||
validationMethod = Some(IgnoreMalformed) | ||||||
) | ||||||
) | ||||||
) && assert(queryWithAllParams)( | ||||||
equalTo( | ||||||
GeoPolygon[TestDocument]( | ||||||
field = "stringField", | ||||||
points = List("40, -70", "30, -80", "20, -90"), | ||||||
queryName = Some("name"), | ||||||
validationMethod = Some(IgnoreMalformed) | ||||||
) | ||||||
) | ||||||
) | ||||||
}, | ||||||
test("hasChild") { | ||||||
val query = hasChild("child", matchAll) | ||||||
val queryWithIgnoreUnmapped = hasChild("child", matchAll).ignoreUnmappedTrue | ||||||
|
@@ -2910,6 +2972,87 @@ object ElasticQuerySpec extends ZIOSpecDefault { | |||||
assert(queryWithValidationMethod.toJson(fieldPath = None))(equalTo(expectedWithValidationMethod.toJson)) && | ||||||
assert(queryWithAllParams.toJson(fieldPath = None))(equalTo(expectedWithAllParams.toJson)) | ||||||
}, | ||||||
test("geoPolygon") { | ||||||
val query = | ||||||
geoPolygon("testField", List("40, -70", "30, -80", "20, -90")) | ||||||
val queryString = | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
geoPolygon(TestDocument.stringField, List("drm3btev3e86", "drm3btev3e87")) | ||||||
val queryWithName = | ||||||
geoPolygon(TestDocument.stringField, List("40, -70", "30, -80", "20, -90")).name("name") | ||||||
val queryWithValidationMethod = | ||||||
geoPolygon(TestDocument.stringField, List("40, -70", "30, -80", "20, -90")).validationMethod( | ||||||
IgnoreMalformed | ||||||
) | ||||||
val queryWithAllParams = | ||||||
geoPolygon(TestDocument.stringField, List("40, -70", "30, -80", "20, -90")) | ||||||
.validationMethod(IgnoreMalformed) | ||||||
.name("name") | ||||||
|
||||||
val expected = | ||||||
""" | ||||||
|{ | ||||||
| "geo_polygon": { | ||||||
| "testField": { | ||||||
| "points": ["40, -70", "30, -80", "20, -90"] | ||||||
| } | ||||||
| } | ||||||
|} | ||||||
|""".stripMargin | ||||||
|
||||||
val expectedWithString = | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
""" | ||||||
|{ | ||||||
| "geo_polygon": { | ||||||
| "stringField": { | ||||||
| "points": ["drm3btev3e86", "drm3btev3e87"] | ||||||
| } | ||||||
| } | ||||||
|} | ||||||
|""".stripMargin | ||||||
|
||||||
val expectedWithName = | ||||||
""" | ||||||
|{ | ||||||
| "geo_polygon": { | ||||||
| "_name": "name", | ||||||
| "stringField": { | ||||||
| "points": ["40, -70", "30, -80", "20, -90"] | ||||||
| } | ||||||
| } | ||||||
|} | ||||||
|""".stripMargin | ||||||
|
||||||
val expectedWithValidationMethod = | ||||||
""" | ||||||
|{ | ||||||
| "geo_polygon": { | ||||||
| "validation_method": "IGNORE_MALFORMED", | ||||||
| "stringField": { | ||||||
| "points": ["40, -70", "30, -80", "20, -90"] | ||||||
| } | ||||||
| } | ||||||
|} | ||||||
|""".stripMargin | ||||||
|
||||||
val expectedWithAllParams = | ||||||
""" | ||||||
|{ | ||||||
| "geo_polygon": { | ||||||
| "validation_method": "IGNORE_MALFORMED", | ||||||
| "_name": "name", | ||||||
| "stringField": { | ||||||
| "points": ["40, -70", "30, -80", "20, -90"] | ||||||
| } | ||||||
| } | ||||||
|} | ||||||
|""".stripMargin | ||||||
|
||||||
assert(query.toJson(fieldPath = None))(equalTo(expected.toJson)) && | ||||||
assert(queryString.toJson(fieldPath = None))(equalTo(expectedWithString.toJson)) && | ||||||
assert(queryWithName.toJson(fieldPath = None))(equalTo(expectedWithName.toJson)) && | ||||||
assert(queryWithValidationMethod.toJson(fieldPath = None))(equalTo(expectedWithValidationMethod.toJson)) && | ||||||
assert(queryWithAllParams.toJson(fieldPath = None))(equalTo(expectedWithAllParams.toJson)) | ||||||
}, | ||||||
test("hasChild") { | ||||||
val query = hasChild("child", matches(TestDocument.stringField, "test")) | ||||||
val queryWithIgnoreUnmapped = hasChild("child", matches("field", "value")).ignoreUnmappedTrue | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Omit one empty line.