How to make exact phrase matching in elastic search? How to make exact phrase matching in elastic search? elasticsearch elasticsearch

How to make exact phrase matching in elastic search?


My guts tell me that your index has 5 primary shards and you don't have enough documents for the scores to be relevant. If you create an index with a single primary shard, your first query will return the document you expect. You can read more about the reason why this happens in the following article: https://www.elastic.co/blog/practical-bm25-part-1-how-shards-affect-relevance-scoring-in-elasticsearch

One way to achieve what you want is by using the keyword type but with a normalizer to lowercase the data so it's easier to search for exact matches in a case insensitive way.

Create your index like this:

PUT english{  "settings": {    "analysis": {      "normalizer": {        "lc_normalizer": {          "type": "custom",          "filter": ["lowercase"]        }      }    }  },  "mappings": {    "sentences": {      "properties": {        "sentence": {          "type": "text",          "fields": {            "exact": {              "type": "keyword",              "normalizer": "lc_normalizer"            }          }        }      }    }  }}

Then you can index your documents as usual.

PUT english/sentences/1{"sentence": "Today is a sunny day"}PUT english/sentences/2{"sentence": "Today is a sunny day but tomorrow it might rain"}...

Finally you can search for an exact phrase match, the query below will only return doc1

POST english/_search{  "query": {    "match": {      "sentence.exact": "today is a sunny day"    }  }}


Try using a bool query

    PUT test_index/doc/1    {"sentence": "Today is a sunny day"}    PUT test_index/doc/2    {"sentence": "Today is a sunny day but tomorrow it might rain"} -#terms query for exact match with keyword and multi match - phrase for other matches    GET test_index/_search    {      "query": {        "bool": {          "should": [            {              "terms": {                "sentence.keyword": [                  "Today is a sunny day"                ]              }            },            {                "multi_match":{                  "query":"Today is a sunny day",                "type":"phrase",                "fields":[                      "sentence"                ]              }            }          ]        }      }    }

Another option use multi match for both with keyword match as first and boost of 5 and other matches with no boost:

PUT test_index/doc/1{"sentence": "Today is a sunny day"}PUT test_index/doc/2{"sentence": "Today is a sunny day but tomorrow it might rain"}GET test_index/_search{    "query":{      "bool":{        "should":[          {            "multi_match":{              "query":"Today is a sunny day",            "type":"phrase",            "fields":[                "sentence.keyword"            ],            "boost":5          }        },        {            "multi_match":{              "query":"Today is a sunny day",            "type":"phrase",            "fields":[                  "sentence"            ]          }        }      ]    }  }}


This Query will work -

{    "query":{        "match_phrase":{            "sentence":{                "query":"Today is a sunny day"            }        }    },    "size":5,    "from":0,    "explain":false}