djangoelasticsearchsearchelastic-stackspring-data-elasticsearch

Use Multiple analyzer in elastic search.(Autocomplete and phonetic)


The analysis algorithm is performing well on autocomplete with fuzzy matching but the fuzzy matching is not soo good so i wanted to add phonetic analyzer to same firstname index. i ran through many documentation and didnot find good one on how to use 2 analyzer.

  "settings": {
    "analysis": {
      "analyzer": {
        "autocomplete_analyzer": {
          "type": "custom",
          "tokenizer": "autocomplete_tokenizer",
          "filter": [
            "lowercase"
          ]
        },
        "phonetic_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "phonetic"
          ]
        }
      },
      "tokenizer": {
        "autocomplete_tokenizer": {
          "type": "edge_ngram",
          "min_gram": 2,
          "max_gram": 10,
          "token_chars": ["letter", "digit"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "full_name": {
        "type": "text",
        "analyzer": "autocomplete_analyzer"
      },
      "relation_name": {
        "type": "text",
      },
      "address": {
        "type": "text"
      }
    }
  }
}

Solution

  • Tricky Answer ...

    while its not possible to use multiple analyzers for a single field (except that you can use different analyzers while index or search), a tricky way to do so is to use the copy_to feature in elasticsearch.

    So you can add another field, e.g. full_name_phonetic as below and while search, query on both fields.

    {
    "mappings": {
        "properties": {
          "full_name_phonetic": {
            "type": "text",
            "analyzer": "phonetic_analyzer"
          },
          "full_name": {
            "type": "text",
            "copy_to": "full_name_phonetic"
            "analyzer": "autocomplete_analyzer"
          },
          "relation_name": {
            "type": "text",
          },
          "address": {
            "type": "text"
          }
        }
      }
    }