-
Notifications
You must be signed in to change notification settings - Fork 17
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 multiMatch
query
#305
(dsl): Support multiMatch
query
#305
Conversation
*/ | ||
final def multiMatch(value: String): MultiMatchQuery[Any] = | ||
MultiMatch(fields = None, value = value) | ||
|
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.
Because fields are optional and type-safe method is now in HasFields
trait, i suppose we don't need multiMatch
type-safe method?
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.
If you change fields
inside of query, this will then be: fields=Chunk.empty
@@ -584,6 +585,25 @@ private[elasticsearch] final case class MatchPhrase[S](field: String, value: Str | |||
) | |||
} | |||
|
|||
sealed trait MultiMatchQuery[S] extends ElasticQuery[S] with HasFields[MultiMatchQuery[S]] | |||
|
|||
private[elasticsearch] final case class MultiMatch[S](fields: Option[Chunk[String]], value: String) |
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 also add minimum_should_match
and boost
parameters, as they are already implemented, and can be applied to this query.
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.
Also, @arnoldlacko @drmarjanovic, what do you think, do we need Types of multi_match query
as additional parameter?
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 think it could make sense to allow something like .matchingType(MultiMatchType.Phrase)
.
If it's more complex, it could also be a separate PR.
def fields[S1: Schema](fields: Field[S1, String]*): MultiMatchQuery[S] = | ||
self.copy(fields = Some(Chunk.fromIterable(fields.map(_.toString)))) |
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 maybe we should just have fields without option, as it is list, it can always be empty, and that way we will cover need for option.
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.
So here, we can have method which only adds new field to the list of fields.
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.
Also, some sort of restrictions should be discussed, as (I think) we can not have both type-safe and raw fields. @arnoldlacko what do you think?
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 think given that we use _.toString
here, the resulting query is the same regardless of being constructed using Field or raw strings, so it does not need to be an issue if they are mixed.
What I wonder is why we have a S1
type here with no defined relation to S
, and why it does not affect the type of the resulting query. We might want to aim for something like:
fields[S1 <: S: Schema](fields: Field[S1, String]*): MultiMatchQuery[S1]
@mvelimir any thoughts?
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'll definitely need S1
to be a subtype of S
, to narrow the type which will always start from Any
based on the constructor method. Also, I think mixing both type-safe fields and plain strings should be allowed, since strings in this case can be used as wildcards, and having type-safe fields will still be useful in inferring the type of the document. Also, the type-safe method should definitely contain at least one field as to not clash with the strings method when the argument list is empty. With all this in mind, I think the method signature should be:
def fields[S1 <: S: Schema](field: Field[S1, String], fields: Field[S1, String]*): MultiMatchQuery[S1]
title: "Multi Match Query" | ||
--- | ||
|
||
The `MultiMatch` query builds on the `match` query to allow multi-field queries: |
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.
This seems to be unfinished?
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 :
.
val query: MultiMatchQuery = multiMatch(value = "test") | ||
``` | ||
|
||
You can create a `MultiMatch` query with fields that will be searched using the `multiMatch` method this way: |
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 use existing syntax:
If you want to change fields
, you can use the fields
method:
*/ | ||
final def multiMatch(value: String): MultiMatchQuery[Any] = | ||
MultiMatch(fields = None, value = value) | ||
|
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.
If you change fields
inside of query, this will then be: fields=Chunk.empty
def fields(fields: String*): Q | ||
|
||
/** | ||
* Sets the `fields` parameter for this [[zio.elasticsearch.query.ElasticQuery]]. The `fields` parameter is the |
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.
* Sets the `fields` parameter for this [[zio.elasticsearch.query.ElasticQuery]]. The `fields` parameter is the | |
* Sets the type-safe `fields` parameter for this [[zio.elasticsearch.query.ElasticQuery]]. The `fields` parameter is the |
56b9e26
to
ecfe1ce
Compare
|
||
private[elasticsearch] object MultiMatchType extends Enumeration { | ||
type MultiMatchType = String | ||
val BestFields = "best_fields" |
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 sort this:
BestFields
BoolPrefix
CrossFields
MostFields
Phrase
PhrasePrefix
private[elasticsearch] final case class MultiMatch[S]( | ||
fields: Chunk[String], | ||
value: String, | ||
matchingType: Option[MultiMatchType], |
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 boost
before matchingType
.
title: "Multi Match Query" | ||
--- | ||
|
||
The `MultiMatch` query builds on the `match` query to allow multi-field queries: |
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 :
.
val query: MultiMatchQuery = multiMatch(value = "test").fields("stringField1", "stringField2") | ||
``` | ||
|
||
If you want to change the [type-safe](https://lambdaworks.github.io/zio-elasticsearch/overview/overview_zio_prelude_schema) `fields` that will be searched, you can use the `fields` method this way: |
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.
If you want to change the [type-safe](https://lambdaworks.github.io/zio-elasticsearch/overview/overview_zio_prelude_schema) `fields` that will be searched, you can use the `fields` method this way: | |
If you want to change the `fields` that will be searched, you can use the `fields` method with the [type-safe](https://lambdaworks.github.io/zio-elasticsearch/overview/overview_zio_prelude_schema) parameters this way: |
val query: MultiMatchQuery = multiMatch(value = "test").fields(Document.stringField1, Document.stringField2) | ||
``` | ||
|
||
If you want to change the `type` of `MultiMatch` query, you can use the `matchingType` method: |
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.
If you want to change the `type` of `MultiMatch` query, you can use the `matchingType` method: | |
If you want to change the `type`, you can use the `matchingType` method: |
```scala | ||
import zio.elasticsearch.query.MultiMatchType | ||
|
||
val query: MultiMatchQuery = multiMatch(value = "test").fields(Document.stringField1, Document.stringField2).matchingType(MultiMatchType.MostFields) |
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.
val query: MultiMatchQuery = multiMatch(value = "test").fields(Document.stringField1, Document.stringField2).matchingType(MultiMatchType.MostFields) | |
val queryWithType: MultiMatchQuery = multiMatch(value = "test").fields(Document.stringField1, Document.stringField2).matchingType(MultiMatchType.MostFields) |
|
||
If you want to change the `boost`, you can use the `boost` method: | ||
```scala | ||
val query: MultiMatchQuery = multiMatch(value = "test").fields(Document.stringField1, Document.stringField2).boost(2.2) |
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.
val query: MultiMatchQuery = multiMatch(value = "test").fields(Document.stringField1, Document.stringField2).boost(2.2) | |
val queryWithBoost: MultiMatchQuery = multiMatch(value = "test").fields(Document.stringField1, Document.stringField2).boost(2.2) |
* @param matchingType | ||
* the [[zio.elasticsearch.query.MultiMatchType]] value of 'type' parameter |
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 explain possible values for matchingType
.
You can lookup for other places with similar @param.
* @param matchingType | ||
* the [[zio.elasticsearch.query.MultiMatchType]] value of 'type' parameter | ||
* @return | ||
* a new instance of the [[zio.elasticsearch.query.ElasticQuery]] with the `type` parameter set. |
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 as above (an instance..).
def fields(field: String, fields: String*): MultiMatchQuery[S] = | ||
self.copy(fields = Chunk.fromIterable(field +: fields)) |
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.
Does it make sense to add fields to chunk instead of setting it? @drmarjanovic
val queryWithMinimumShouldMatch = multiMatch("this is a test").minimumShouldMatch(2) | ||
val queryWithAllParams = multiMatch("this is a test") | ||
.fields(TestDocument.stringField) | ||
.matchingType(MultiMatchType.BestFields) |
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 omit MultiMatchType
? (everywhere in file)
@@ -2505,13 +2608,120 @@ object ElasticQuerySpec extends ZIOSpecDefault { | |||
| "stringField": { | |||
| "query" : "test" | |||
| } | |||
| } | |||
| } |
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.
Was this on purpose?
|
||
package zio.elasticsearch.query | ||
|
||
private[elasticsearch] object MultiMatchType extends Enumeration { |
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 refer to the existing classes that represent enumerations.
If you want to change the `type`, you can use the `matchingType` method: | ||
```scala | ||
import zio.elasticsearch.query.MultiMatchType | ||
import zio.elasticsearch.query.MultiMatchType._ | ||
|
||
val query: MultiMatchQuery = multiMatch(value = "test").fields(Document.stringField1, Document.stringField2).matchingType(MultiMatchType.MostFields) | ||
val queryWithType: MultiMatchQuery = multiMatch(value = "test").fields(Document.stringField1, Document.stringField2).matchingType(MultiMatchType.MostFields) | ||
``` | ||
|
||
If you want to change the `boost`, you can use the `boost` method: | ||
```scala | ||
val query: MultiMatchQuery = multiMatch(value = "test").fields(Document.stringField1, Document.stringField2).boost(2.2) | ||
val queryWithBoost: MultiMatchQuery = multiMatch(value = "test").fields(Document.stringField1, Document.stringField2).boost(2.2) | ||
``` |
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.
Put boost
first, then minimum_should_match
, then type
.
case object CrossFields extends MultiMatchType { def value: String = "cross_fields" } | ||
case object MostFields extends MultiMatchType { def value: String = "most_fields" } | ||
case object Phrase extends MultiMatchType { def value: String = "phrase_fields" } | ||
case object PhrasePrefix extends MultiMatchType { def value: String = "phrase_prefix" } | ||
} |
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.
Put empty line at the end.
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.
If you mean at the end of file, sbt prepare removes it
sealed trait MultiMatchType { | ||
def value: String | ||
override def toString: String = value | ||
} |
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 this is overkill, also, I think value
should not be visible to users.
My advice is this: put only override def toString: String = value
to each case object.
*/ | ||
def fields(field: String, fields: String*): MultiMatchQuery[S] | ||
|
||
/** | ||
* Sets the type-safe `fields` parameter for this [[zio.elasticsearch.query.ElasticQuery]]. The `fields` parameter is | ||
* the type-safe array of fields that will be searched. | ||
* the array of type-safe fields that will be searched. |
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 the
.
* the [[zio.elasticsearch.query.MultiMatchType]] value of 'type' parameter, possible values are: | ||
* - [[zio.elasticsearch.query.MultiMatchType.BestFields]] | ||
* - [[zio.elasticsearch.query.MultiMatchType.BoolPrefix]] | ||
* - [[zio.elasticsearch.query.MultiMatchType.CrossFields]] | ||
* - [[zio.elasticsearch.query.MultiMatchType.MostFields]] | ||
* - [[zio.elasticsearch.query.MultiMatchType.Phrase]] | ||
* - [[zio.elasticsearch.query.MultiMatchType.PhrasePrefix]] |
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, provide short explanation for each value. You can see scaladoc
for scoreMode
def.
.map( | ||
"minimum_should_match" -> _.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.
Can this be in one line? Or better formatted?
case object MostFields extends MultiMatchType { def value: String = "most_fields" } | ||
case object Phrase extends MultiMatchType { def value: String = "phrase_fields" } | ||
case object PhrasePrefix extends MultiMatchType { def value: String = "phrase_prefix" } | ||
case object BestFields extends MultiMatchType { override def toString: String = "best_fields" } |
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 please put defs to new line inside of objects?
Part of #91
Fields parameter is made optional so implementation of this query is a bit different than others.
And should
type
parameter be included and made optional? https://www.elastic.co/guide/en/elasticsearch/reference/7.17/query-dsl-multi-match-query.html#multi-match-types