ElasticSeach combine multi_match and match_phrase - elasticsearch

I use ES 7, I want to search over multi fields, but on this field (title) must be shown firstly if it matches exactly. For now I tried :
{
"query": {
"bool": {
"must": {
"bool": {
"should": [
{
"match_phrase": {
"titre": {
"query": "test",
"boost": "20"
}
}
},
{
"multi_match": {
"fields": ["titre", "description^4", "subtitle^3"],
"query": "test",
"type": "most_fields"
}
}
]
}
}
}
}
}
It works, but I would like to order the match_phrase before other results.
The idea is the user type the exact phrase of a title, this result will appear before other based on multi_match.
Is it possible ?

Related

Named multi_match query

I need a hand here. I have a cross_fields multi_match query and I need to use named queries for each field. I can rewrite it into a bool/should match but then I dont know how to reproduce the cross_fields condition. Any idea? Thanks!
Multimatch query: Relevance OK, but no named queries
GET test_index/_search
{
"query": {
"multi_match": {
"query": "example_query",
"fields": ["name","lastname"],
"type": "cross_fields"
}
}
}
Bool query: Named queries OK but bad relevance
GET test_index/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"name": {
"query": "example query",
"_name": "name_match"
}
}
},
{
"match": {
"latname": {
"query": "example query",
"_name": "latname_match"
}
}
}
]
}
}
}
How does using dismax with tie_breaker: 1.0 work for your ES index?
Something like this:
GET vehicle/_search
{
"query": {
"dis_max": {
"tie_breaker": 1.0,
"queries": [
{
"match": {
"make": {
"query": "Lamborghini",
"_name": "make"
}
}
},
{
"match": {
"model": {
"query": "Diablo",
"_name": "model"
}
}
}
]
}
}
}
The Dismax query is very similar to the multi_match query in that it compares scores across sub clauses/queries. The tie_breaker parameter controls how much losing/non-max fields contributed to the final summation of clause scores, any losing fields scores are multiplied by the tie_breaker. The default tie_breaker: 0.0, which is most similar to type: best_fields in multi_match.

ElasticSearch multimatch substring search

I have to combine two filters to match requirements:
- a specific list of values in r.status field
- one of the multiple text fields contains the value.
Result query (with using Nest, but it doesn't matter) looks like:
{
"query": {
"bool": {
"filter": [
{
"bool": {
"must": [
{
"term": {
"isActive": {
"value": true
}
}
},
{
"nested": {
"query": {
"bool": {
"must": [
{
"terms": {
"r.status": [
"VALUE_1",
"VALUE_2",
"VALUE_3"
]
}
},
{
"bool": {
"should": [
{
"match": {
"r.g.firstName": {
"type": "phrase",
"query": "SUBSTRING_VALUE"
}
}
},
{
"match": {
"r.g.lastName": {
"type": "phrase",
"query": "SUBSTRING_VALUE"
}
}
}
]
}
}
]
}
},
"path": "r"
}
}
]
}
}
]
}
}
}
Also tried with multi_match query:
{
"query": {
"bool": {
"filter": [
{
"bool": {
"must": [
{
"term": {
"isActive": {
"value": true
}
}
},
{
"nested": {
"query": {
"bool": {
"must": [
{
"terms": {
"r.status": [
"VALUE_1",
"VALUE_2",
"VALUE_3"
]
}
},
{
"multi_match": {
"query": "SUBSTRING_VALUE",
"fields": [
"r.g.firstName",
"r.g.lastName"
]
}
}
]
}
},
"path": "r"
}
}
]
}
}
]
}
}
}
FirstName and LastName are configured in index mappings as text:
"firstName": {
"type": "text"
},
"lastName": {
"type": "text"
}
Elastic gives a lot of full-text search options: multi_match, phrase, wildcards etc. But all of them fail in my case looking a sub-string in my text fields. (terms query and isActive one work well, I just tried to run only them).
What options do I have also or maybe where I made a mistake?
UPD: Combined wildcards worked for me, but such query looks ugly. Looking for a more elegant solution.
The elasticsearch way is to use ngram tokenizer.
The ngram analyzer will split your terms with a sliding window. For example, the input "Hello World" will generate the following terms:
Hel
Hell
Hello
ell
ello
...
Wor
World
orl
...
You can configure the minimum and maximum size of the sliding window (in the example the minimum size is 3). Once the sub terms are generated you can use a match query an the subfield.
Another point, it is weird to use must within a filter. If you are interested in the score, you should always use must otherwise use filter. Read this article for a good understanding.

ElasticSearch Multi Match with Multiple Query Parameters

We have the following multi match query in Elastic Search
{
"query": {
"bool": {
"must": {
"multi_match": {
"query": "90803",
"type": "cross_fields",
"fields": [
"POSTAL_CODE^5",
"ADDRESS",
"CITY"
],
"operator": "and"
}
}
}
}}
How can we pass multiple query parameters. For e.g. we want to pass multiple ID in the query to match against the field Postal Code.
First, is POSTAL_CODE an analyzed field? If it's not the case you could use a Terms Query:
{
"query": {
"terms" : {
"POSTAL_CODE" : ["90803", "90809"]
}
}
}
If you want to use Match for some reason, there is not a Match Query that matches several values, you have to use a Bool Query with should or must depending on your use case.
Example with must:
{
"query": {
"bool": {
"must": [{
"match": { "POSTAL_CODE": "90803" }
}, {
"match": { "POSTAL_CODE": "90809" }
}]
}
}
}

Relevance by type on same field in elasticsearch

Is there any way to boost search results on same field depending on type?
My basic boosting is something like:
GET _search
{
"query": {
"simple_query_string": {
"query": "mangan",
"fields":["_all", "title^6"]
}
}
}
But for some other documents I want title to be less important, so I tried to prefix it with type:
GET _search
{
"query": {
"simple_query_string": {
"query": "mangan",
"fields":[
"_all",
"DocumentationPage.title^6",
"DocumentationPage.title^6"]
}
}
}
But then it does not boost at all. As a last resort I could use Funcsion/Script Score bu would like to avoid it.
For sake of example, assume that document contains just title field.
A simple way to achieve this is re-writing the query in the OP as a dis-max query.
Example for elasticsearch 5.x:
{
"query": {
"dis_max": {
"queries": [
{
"simple_query_string": {
"fields": [
"_all"
],
"query": "mangan"
}
},
{
"bool": {
"filter": {
"type": {
"value": "DocumentationPage"
}
},
"must": [
{
"simple_query_string": {
"fields": [
"title^6"
],
"query": "mangan"
}
}
]
}
}
]
}
}
}

Elastic : search two terms, one on _all, other one on a field

I would like to mix a search on a whole document (eg "developer") and a search on some field for another term (eg "php").
I can do each search separately but I can't mix them.
Here my example (simplified to show only my issue) :
{
"query": {
"function_score": {
"query": {
"match": {
"_all": "developer"
},
"multi_match": {
"query": "php",
"fields": [
"skills.description",
"skills.description",
"skills.details"
],
"operator": "or",
"type": "most_fields"
}
}
}
}
If I run this example I have an error :
Parse Failure [Failed to parse source
Is there a way to search on both _all and specific fields with two terms?
Thanks.
Yes, you're almost there, you need to combine them into a bool/must query:
{
"query": {
"function_score": {
"query": {
"bool": {
"must": [
{
"match": {
"_all": "developer"
}
},
{
"multi_match": {
"query": "php",
"fields": [
"skills.description",
"skills.description",
"skills.details"
],
"operator": "or",
"type": "most_fields"
}
}
]
}
}
}
}
}

Resources