fuzziness in bool query with multimatch elasticsearch - elasticsearch

i am using elasticsearch version 6.3.0. I want to use fuzziness along with multimatch. but there is no option for that. Can anybody provide me a solution ? Thanks in advance
Query :
{ "query": {
"bool": {
"must": [
{"function_score": {
"query": {
"multi_match": {
"query": "local",
"fields": [
"user.name^3",
"main_product"
],
"type": "phrase"
}
}
}}
],
"filter": {
"geo_distance": {
"distance": "1000km",
"user.geolocation": {
"lat": 25.55,
"lon": -84.44
}
}
}
}
} }

Looking at your existing query, you are looking for mix of
Boosting based on field
Multifield match
Phrase Matching
Fuzzy Matching
If it isn't phrase_match you can simply add "fuzziness": "AUTO" or "fuzziness":1 or whatever number based on your requirement in your existing query and you'd get what you are looking for.
Fuzzy without Phrase
POST <your_index_name>/_search
{
"query":{
"bool":{
"must":[
{
"function_score":{
"query":{
"multi_match":{
"query":"local",
"fields":[
"user.name^3",
"main_product"
],
"fuzziness":"AUTO"
}
}
}
}
],
"filter":{
"geo_distance":{
"distance":"1000km",
"user.geolocation":{
"lat":25.55,
"lon":-84.44
}
}
}
}
}
}
Fuzzy with Phrase:
In this case, you need to make use of Span Queries
I've discarded the filtering part just for the sake of simplicity and came up with the below query. And let's say that I am searching for phrase called pearl jam.
POST <your_index_name>/_search
{
"query":{
"function_score":{
"query":{
"bool":{
"should":[
{
"bool":{
"boost":3,
"must":[
{
"span_near":{
"clauses":[
{
"span_multi":{
"match":{
"fuzzy":{
"user.name":"pearl"
}
}
}
},
{
"span_multi":{
"match":{
"fuzzy":{
"user.name":"jam"
}
}
}
}
],
"slop":0,
"in_order":true
}
}
]
}
},
{
"bool":{
"boost":1,
"must":[
{
"span_near":{
"clauses":[
{
"span_multi":{
"match":{
"fuzzy":{
"main_product":"pearl"
}
}
}
},
{
"span_multi":{
"match":{
"fuzzy":{
"main_product":"jam"
}
}
}
}
],
"slop":0,
"in_order":true
}
}
]
}
}
]
}
}
}
}
}
So what I am doing is performing boosting based on fields in multi-field phrase with fuzzy match for phrase called pearl jam.
Having slop: 0 and in_order:true would enable me to do phrase match for the words I've specified in the clauses.
Let me know if you have any queries.

What makes you think there is no option for fuzziness on a multi-match query?
For example, with the data below:
http://localhost:9200/question_1/doc/_bulk
{"index":{}}
{"name" : "John Lazy", "text": "lazzi"}
{"index":{}}
{"name" : "John Lassi", "text": "lasso"}
{"index":{}}
{"name" : "Joan Labbe", "text": "lazzy"}
And this query:
http://localhost:9200/question_1/_search
{
"query": {
"multi_match" : {
"query" : "lazi",
"fields" : [ "name", "text" ],
"fuzziness": 1
}
}
}
Then I get one result, but if I change the fuzziness parameter to 2 I'll get three results.

Related

How to use "OR" in Dev Tool Query

Hi Bellow Search provides me Log where it has both "value": "HB" and "value": "1234567" as, I am using Term, however, What I am looking for this if this match
("value": "HB" OR "value": "TR" ) AND "value": "1234567"
but not understanding how to do in below,
Can anyone please help me
GET _search
{ "query": { "bool": { "must": [ { "match": {"log.file.path":"mylog.log" } }
{
"term": {
"GPS-LOG.COMMAND": {
"value": "HB"
}
}
},
{
"term": {
"GPS-LOG.IMEI": {
"value": "1234567"
}
}
}
], "filter": {
"range": {
"#timestamp": {
"gte": "now-10m"
}
} }
} }
At first glace, it seems like this should have a simple solution. However, since you are using the term query, you can only search one value at a time. I don't know your mapping but if you are using a text field you shouldn't be using term query.
However, to solve this using the term query, you have to create the OR operator using the minimum_should_match combined with should.
See the following code:
GET _search
{
"query":{
"bool":{
"must":[
{
"match":{
"log.file.path":"mylog.log"
}
},
{
"term":{
"GPS-LOG.IMEI":{
"value":"1234567"
}
}
},
{
"bool":{
"should":[
{
"term":{
"GPS-LOG.COMMAND":{
"value":"HB"
}
}
},
{
"term":{
"GPS-LOG.COMMAND":{
"value":"TR"
}
}
}
],
"minimum_should_match":1
}
}
],
"filter":{
"range":{
"#timestamp":{
"gte":"now-10m"
}
}
}
}
}
}

Finding matches for two connected fields with fuzziness

I'm trying to search a specific person by his given name and surname. I think the best option to search within two fields simultaneously is a bool query:
{
"query":{
"bool":{
"must":[
{"match": {"name":"Martin"}},
{"match": {"surname":"Mcfly"}}
]
}
}
}
But bool queries don't seem to support fuzziness. So what could I do to find the person "Marty Mcfly" since this match isn't found by the above query. I also would like to be ably to find someone like "Marty J. Mcfly" if it's possible.
bool is just a wrapper to join AND/OR/NOT/FILTER operations.
In your case it would make sense to use multi_match query:
{
"query":{
"bool":{
"must":[
{
"multi_match":{
"query":"Marty J. Mcfly",
"operator": "and",
"fields":[
"name",
"surname"
]
}
}
]
}
}
}
This will search data in both name and surname fields and ensure that all terms must match in both of your fields.
Updated
{
"query": {
"bool": {
"must": [
{
"match": {
"name": {
"query": "Martin",
"operator": "and",
"fuzziness": 1
}
}
},
{
"match": {
"surname": {
"query": "Mcfly",
"operator": "and",
"fuzziness": 1
}
}
}
]
}
}
}

Query based on Fields existing in different Indices in Elasticsearch

I've got the following query
{
"from":0,
"size":50000,
"_source":[
"T121",
"timestamp"
],
"sort":{
"timestamp":{
"order":"asc"
}
},
"query":{
"bool":{
"must":{
"range":{
"timestamp":{
"gte":"2017-01-17 11:44:41.347",
"lte":"2017-02-18 11:44:47.878"
}
}
},
"must":{
"exists":{
"field":"T121"
}
}
}
}
}
http://172.22.23.169:9200/index1,index2,Index3/_search?pretty
With this URL i want to query over a number of indices in Elasticsearch and only return those documents where a specific field exists.
Is it possible to put in a list of fields in the "exists" clause where i define
if "field1" OR "field2" OR "fiedl3" are existing in one of the documents return it, otherwise don't, or do i have to script such a case?
To search across all indices use > http://172.22.23.169:9200/_search?pretty
To search across selected indices add following filter to "bool" filter
"must": {
"terms": {
"_index": [
"index1",
"index2"
]
}
}
For OR'ing multiple "exists", you can use should clause with multiple exists and specify "minimum_should_match" to control searched records.
{
"from":0,
"size":50000,
"_source":[
"T121",
"timestamp"
],
"sort":{
"timestamp":{
"order":"asc"
}
},
"query":{
"bool":{
"must":{
"range":{
"timestamp":{
"gte":"2017-01-17 11:44:41.347",
"lte":"2017-02-18 11:44:47.878"
}
}
},
"should":[
{
"exists":{
"field":"field1"
}
},
{
"exists":{
"field":"field2"
}
},
{
"exists":{
"field":"field3"
}
}
]
}
}
}

how to know which keywords matched in elasticsaearch

Say that I query:
POST /story/story/_search
{
"query":{
"bool":{
"should":[
{
"match":{
"termVariations":{
"query":"not driving",
"type":"boolean",
"operator":"AND"
}
}
},
{
"match":{
"termVariations":{
"query":"driving",
"type":"boolean",
"operator":"AND"
}
}
}
]
}
}
}
This query returned by one analyzer or another 3 documents.
How do I tell which should clause was matched? Can Elasticsearch return the matched phrase along with the result?
Thanks!
The best option here would be named queries.
You can name your query and the name of the queries that matched would be provided per document.
{
"query": {
"bool": {
"should": [
{
"match": {
"name.first": {
"query": "qbox",
"_name": "first"
}
}
},
{
"match": {
"name.last": {
"query": "search",
"_name": "last"
}
}
}
]
}
}
}
Thanks #keety! highlight was exactly what I was looking for!! :-)

Elastic search filtered query, query part being ignored?

I'm building up the following search in code, the idea being that it filters down the set of matches then queries this so I can add score based on certain fields. For some reason the filter part works but whatever I put in the query (i.e. in the below I have no index sdfsdfsdf) it still returns anything matching the filter.
Is the syntax wrong?
{
"query":{
"filtered":{
"query":{
"bool":{
"must":{
"match":{
"sdfsdfsdf":{
"query":"4",
"boost":2.0
}
}
}
},
"filter":{
"bool":{
"must":[
{
"terms":{
"_id":[
"55f93ead5df34f1900abc20b",
"55f8ab0226ec4bb216d7c938",
"55dc4e949dcf833308c63d6b"
]
}
},
{
"range":{
"published_date":{
"lte":"now"
}
}
}
],
"must_not":{
"terms":{
"_id":[
"55f0a799acccc28204a5058c"
]
}
}
}
}
}
}
}
}
Your filter is not at the right level. It should not be inside query but at the same level as query like this:
{
"query": {
"filtered": {
"query": { <--- query and filter at the same level
"bool": {
"must": {
"match": {
"sdfsdfsdf": {
"query": "4",
"boost": 2
}
}
}
}
},
"filter": { <--- query and filter at the same level
"bool": {
"must": [
{
"terms": {
"_id": [
"55f93ead5df34f1900abc20b",
"55f8ab0226ec4bb216d7c938",
"55dc4e949dcf833308c63d6b"
]
}
},
{
"range": {
"published_date": {
"lte": "now"
}
}
}
],
"must_not": {
"terms": {
"_id": [
"55f0a799acccc28204a5058c"
]
}
}
}
}
}
}
}
You need to replace sdfsdfsdf with your existing field name in your type, e.g. title, otherwise I think it will fallback to match_all query.
"match":{
"title":{
"query": "some text here",
"boost":2.0
}
}

Resources