-
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 highlights #141
Conversation
modules/library/src/main/scala/zio/elasticsearch/ElasticHighlight.scala
Outdated
Show resolved
Hide resolved
def highlight[S](field: Field[S, _], fieldConfig: Map[String, Json]): Highlights = | ||
Highlights(Chunk(HighlightField(field.toString, fieldConfig))) | ||
|
||
def highlight(field: String, fieldConfig: Map[String, Json] = Map.empty): Highlights = |
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.
Can we use config
instead of fieldConfig
?
@@ -69,10 +70,17 @@ object ElasticRequest { | |||
GetById(index = index, id = id, refresh = None, routing = None) | |||
|
|||
def search(index: IndexName, query: ElasticQuery[_]): SearchRequest = | |||
Search(index = index, query = query, sortBy = Set.empty, routing = None) | |||
Search(index = index, query = query, sortBy = Set.empty, routing = None, highlights = None) |
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.
Let's put this before routing
. Let's use sorted params.
aggregation = aggregation, | ||
sortBy = Set.empty, | ||
routing = None, | ||
highlights = None |
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.
Same here.
@@ -311,16 +319,29 @@ object ElasticRequest { | |||
with HasRouting[SearchRequest] | |||
with WithSort[SearchRequest] { | |||
def aggregate(aggregation: ElasticAggregation): SearchAndAggregateRequest | |||
def highlights(value: Highlights): Search |
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.
I'm thinking about highlighted(highlights: Highlights)
. What do you think? Also, add a new line before.
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.
Maybe to use highlight
to have meaning as a verb. (I want this search and highlight this)
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.
Can you add a new line before?
import zio.json.ast.Json | ||
import zio.json.ast.Json.Obj | ||
|
||
case class Highlights(fields: Chunk[HighlightField], globalConfig: HighlightConfig = Map.empty) { self => |
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.
Let's add final
here.
import zio.json.ast.Json | ||
import zio.json.ast.Json.Obj | ||
|
||
case class Highlights(fields: Chunk[HighlightField], globalConfig: HighlightConfig = Map.empty) { self => |
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.
Can we use config
here instead of globalConfig
?
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.
We have config parameter in method, maybe it would not be clear.
def withGlobalConfig(configFieldName: String, config: Json): Highlights = | ||
self.copy(globalConfig = self.globalConfig.updated(configFieldName, config)) | ||
|
||
def withHighlight(fieldName: String, fieldConfig: HighlightConfig = Map.empty): Highlights = |
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.
Do we need Field
here also? And maybe use field
instead of fieldName
.
Alos, I would use config
instead of fieldConfig
.
case class Highlights(fields: Chunk[HighlightField], globalConfig: HighlightConfig = Map.empty) { self => | ||
def toJson: Json = Obj("highlight" -> Obj(configList: _*).merge(fieldsList)) | ||
|
||
def withGlobalConfig(configFieldName: String, config: Json): Highlights = |
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.
I would use field
here as well.
type HighlightConfig = Map[String, Json] | ||
} | ||
|
||
case class HighlightField(fieldName: String, fieldConfig: HighlightConfig = Map.empty) { |
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.
Can we use field
and config
?
Also, we are missing final
.
case (Some(s), Some(h)) => r.query.toJson merge s merge h | ||
case (Some(s), _) => r.query.toJson merge s | ||
case (_, Some(h)) => r.query.toJson merge h | ||
case _ => r.query.toJson |
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.
I would use explicit None
(when _
only stands for None
or (None, None)
), so that cases could be easily reordered without changing the meaning.
modules/library/src/main/scala/zio/elasticsearch/ElasticHighlight.scala
Outdated
Show resolved
Hide resolved
modules/library/src/main/scala/zio/elasticsearch/ElasticHighlight.scala
Outdated
Show resolved
Hide resolved
b442cbd
to
654a79f
Compare
@@ -311,16 +319,29 @@ object ElasticRequest { | |||
with HasRouting[SearchRequest] | |||
with WithSort[SearchRequest] { | |||
def aggregate(aggregation: ElasticAggregation): SearchAndAggregateRequest | |||
def highlights(value: Highlights): Search |
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.
Can you add a new line before?
@@ -360,7 +364,10 @@ private[elasticsearch] final class HttpExecutor private (esConfig: ElasticConfig | |||
case HttpOk => | |||
response.body.fold( | |||
e => ZIO.fail(new ElasticException(s"Exception occurred: ${e.getMessage}")), |
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.
Move => ZIO.fail
to new line as well.
@@ -463,7 +470,15 @@ private[elasticsearch] final class HttpExecutor private (esConfig: ElasticConfig | |||
case HttpOk => | |||
response.body.fold( | |||
e => ZIO.fail(new ElasticException(s"Exception occurred: ${e.getMessage}")), |
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.
Same here.
} | ||
|
||
final case class HighlightField(field: String, config: HighlightConfig = Map.empty) { | ||
def toStringJsonPair: (String, Obj) = field -> Obj(config.toList: _*) |
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.
Is this visible to the user?
|
||
def withExplicitFieldOrder: Highlights = self.copy(explicitFieldOrder = true) | ||
|
||
private def configList: List[(String, Json)] = config.toList |
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.
Please add a new line between. Can we use lazy val
instead?
def documentAs[A](implicit schema: Schema[A]): Either[DecodeError, A] = JsonDecoder.decode(schema, raw.toString) | ||
|
||
lazy val highlights: Option[Map[String, Chunk[String]]] = highlight.flatMap { json => | ||
json.toString.fromJson[Map[String, Chunk[String]]] match { |
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.
Can you use .toOption
only?
@@ -63,6 +63,8 @@ final class SearchResult private[elasticsearch] (private val hits: List[Item]) e | |||
DecodingException(s"Could not parse all documents successfully: ${errors.map(_.message).mkString(",")})") | |||
} | |||
} | |||
|
|||
def items: ZIO[Any, Nothing, List[Item]] = ZIO.succeed(hits) |
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.
We should use alias for ZIO[Any, Nothing, A]
.
config: HighlightConfig = Map.empty, | ||
explicitFieldOrder: Boolean = false | ||
) { self => | ||
def toJson: Json = Obj("highlight" -> Obj(configList: _*).merge(fieldsList)) |
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.
I would use private[elasticsearch]
here at least.
modules/library/src/main/scala/zio/elasticsearch/highlighting/Highlights.scala
Outdated
Show resolved
Hide resolved
config: HighlightConfig = Map.empty, | ||
explicitFieldOrder: Boolean = false | ||
) { self => | ||
def withExplicitFieldOrder: Highlights = self.copy(explicitFieldOrder = true) |
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.
Can you move this to the new line?
c0a5599
to
ef89dca
Compare
@@ -549,6 +553,158 @@ object HttpExecutorSpec extends IntegrationSpec { | |||
Executor.execute(ElasticRequest.deleteIndex(firstSearchIndex)).orDie | |||
) | |||
) @@ shrinks(0), | |||
suite("searching for documents with highlights")( | |||
test("successfully find document and return highlight") { |
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.
Maybe return document and highlight/with highlight
?
Executor.execute(ElasticRequest.createIndex(firstSearchIndex)), | ||
Executor.execute(ElasticRequest.deleteIndex(firstSearchIndex)).orDie | ||
), | ||
test("successfully find document and return highlight using field accessor") { |
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.
Same here.
Executor.execute(ElasticRequest.createIndex(firstSearchIndex)), | ||
Executor.execute(ElasticRequest.deleteIndex(firstSearchIndex)).orDie | ||
), | ||
test("successfully find document and return highlights map") { |
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.
Same.
Executor.execute(ElasticRequest.createIndex(firstSearchIndex)), | ||
Executor.execute(ElasticRequest.deleteIndex(firstSearchIndex)).orDie | ||
), | ||
test("successfully find document and use global config to return highlight") { |
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.
Maybe return document and highlight using global config
?
Executor.execute(ElasticRequest.createIndex(firstSearchIndex)), | ||
Executor.execute(ElasticRequest.deleteIndex(firstSearchIndex)).orDie | ||
), | ||
test("successfully find document and use local config to overwrite global config and return highlight") { |
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.
Same?
* limitations under the License. | ||
*/ | ||
|
||
package zio.elasticsearch.highlighting |
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.
Why not just highlight?
def withHighlight(field: Field[_, _]): Highlights = | ||
withHighlight(field.toString, Map.empty) |
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.
In Aggregations and Queries order of methods was like this:
method(f: Field[_, _])
method(f: String),
so maybe we could do same here?
|
||
private lazy val configList: List[(String, Json)] = config.toList | ||
|
||
private lazy val fieldsList: Obj = |
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.
You have configList: List[(String, String)]
above, and here fieldsList: Obj
.
Maybe we should call this fieldsListJson
?
def toJson: Json = { | ||
val baseJson = (self.from, self.size) match { | ||
case (Some(from), Some(size)) => | ||
Obj("from" -> from.toJson) merge Obj("size" -> size.toJson) merge self.query.toJson | ||
case (Some(from), None) => | ||
Obj("from" -> from.toJson) merge self.query.toJson | ||
case (None, Some(size)) => | ||
Obj("size" -> size.toJson) merge self.query.toJson | ||
case _ => | ||
self.query.toJson | ||
} | ||
val fromJson: Json = self.from.map(f => Obj("from" -> f.toJson)).getOrElse(Obj()) | ||
|
||
sortBy match { | ||
case sorts if sorts.nonEmpty => | ||
baseJson merge Obj("sort" -> Arr(self.sortBy.toList.map(_.paramsToJson): _*)) merge aggregation.toJson | ||
case _ => | ||
baseJson merge aggregation.toJson | ||
} | ||
val sizeJson: Json = self.size.map(s => Obj("size" -> s.toJson)).getOrElse(Obj()) | ||
|
||
val highlightsJson: Json = self.highlights.map(_.toJson).getOrElse(Obj()) | ||
|
||
val sortJson: Json = | ||
if (self.sortBy.nonEmpty) Obj("sort" -> Arr(self.sortBy.toList.map(_.paramsToJson): _*)) else Obj() | ||
|
||
fromJson merge sizeJson merge highlightsJson merge sortJson merge self.query.toJson | ||
} | ||
} |
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.
You are missing aggregations here.
_ = println(docs) | ||
_ = println(aggs) |
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.
Remove prints
No description provided.