Exact match Query: ex: When I am trying to search for marble flooring the following matches should be fetched

When I am trying to search for marble flooring the following matches should be fetched

  1. marble flooring
  2. marbles flooring
  3. flooring marble
  4. flooring marbles
  5. marble floor
  6. marbles floor
  7. marble
  8. marbles
  9. flooring
  10. floor
{
  "size": 100,
  "query": {
      "bool": {
          "must": [
              {
                  "multi_match": {
                      "query": "marble flooring",
                      "fields": [
                          "title^3",
                          "keywords.key_value^2",
                          "services.name^1"
                      ],
                      "type": "best_fields",
                      "operator": "and"
                  }
              }
          ]
      }
  }
}

as I dont want to use fuzziness, due to fuzziness. when am searching for a table, in the results i am getting the results for cable as well

What is the mapping of the fields you are searching? Based on your expected matches it looks like you may need to use a custom analyser that includes a stemmer.

mappings

"keywords": {
    "type": "object",
    "enabled": True,
    "properties": {
        "name": {
            "type": "text",
            "analyzer": "synonym_analyzer"
        }
    }
}

settings

"analyzer": {
    "synonym_analyzer": {
    "tokenizer": "whitespace",
    "filter": [ "stemmer" ]
    }
}

this the the mapping and analyzer which i have used

Can you please use the get mapping API to show us the exact mapping of the 3 fields you are querying? This should allow you to verify that the fields you are querying actually have the mapping you showed.

Once you have done this you can use the analyze API to test how your analyzer tokenizes the various string you query with and expect to match.

mappings

"keywords": {
    "properties": {
        "keyword_values": {
            "type": "text",
            "fields": {
                "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                }
            }
        },
        "name": {
            "type": "text",
            "analyzer": "synonym_analyzer"
        }
    }
}

analyze

{
    "tokens": [
        {
            "token": "marbl",
            "start_offset": 0,
            "end_offset": 6,
            "type": "word",
            "position": 0
        },
        {
            "token": "floor",
            "start_offset": 7,
            "end_offset": 15,
            "type": "word",
            "position": 1
        }
    ]
}

It looks like you are not searching the keywords.name field which is the one with the custom analyser and instead are searching the keywords.keyword_values field, which uses the default analyser and has no stemmer.

mappings

"keywords": {
    "properties": {
        "name": {
            "type": "text",
            "fields": {
                "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                }
            }
        },
        "name": {
            "type": "text",
            "analyzer": "synonym_analyzer"
        }
    }
}

analyze

{
    "tokens": [
        {
            "token": "marbl",
            "start_offset": 0,
            "end_offset": 6,
            "type": "word",
            "position": 0
        },
        {
            "token": "floor",
            "start_offset": 7,
            "end_offset": 15,
            "type": "word",
            "position": 1
        }
    ]
}

this is the updated one

Where are the mappings coming from? It looks like you have a duplicate name field definition (not valid JSON), which makes me suspect it is not part of the output from the get mappings API.

{{URL}}/indexname/_mapping

{
    "indexname": {
        "mappings": {
            "properties": {
                "keywords": {
                    "properties": {
                        "key_name": {
                            "type": "text",
                            "fields": {
                                "keyword": {
                                    "type": "keyword",
                                    "ignore_above": 256
                                }
                            }
                        },
                        "name": {
                            "type": "text",
                            "analyzer": "synonym_stemmer_bad_words_analyzer"
                        }
                    }
                }
            }
        }
    }
}

from here i got the response

Here you can see that the two properties are named key_name and name, which is different from the previous post. To use the stemmer you need to query the keywords.name field and not keywords.key_name . The query you posted shows you querying keywords.key_value, which apparently does not exist.

If you are going to alter the output and not show real field names please make sure it is correct.