How highlight partial word when using edge_ngram filter

Viewed 154

I am using the edge_ngram filter in my analyzer, e.g. I index a word "EVA京", it will be mapped to an array [E, EV, EVA, 京]. And then I search "EV", of cause "EVA京" can be recalled. But the highlight works wrong! The result of highlight is "<em>EVA</em>京", but not "<em>EV</em>A京".

Can someone give me a hint how to correct the highlight result?

My index settings and mappings:

PUT my-index-001
{
  "settings": {
    "analysis": {
      "filter": {
        "edge_ngram_1_100": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 100
        }
      },
      
      "analyzer": {
        "my_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": ["lowercase", "edge_ngram_1_100"]
        }
      }
    }
  }, 
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "my_analyzer",
        "search_analyzer": "standard"
      }
    }
  }
}

And then add a sentence:

PUT my-index-001/_doc/1
{
  "name": "EVA新世纪福音战士"
}

And then I search:

GET my-index-001/_search
{
  "query": {
    "match": {
      "name": {
        "query": "EV"
        , "operator": "and"
      }
    }
  }
  , "highlight": {
    "fields": {
      "name": {
      }
    }
  }
}

The result of searching is:

{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.3133171,
    "hits" : [
      {
        "_index" : "my-index-001",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.3133171,
        "_source" : {
          "name" : "EVA新世纪福音战士"
        },
        "highlight" : {
          "name" : [
            "<em>EVA</em>新世纪福音战士"
          ]
        }
      }
    ]
  }
}
1 Answers

If you need to highlight the result of partial word match of the document, then you can achieve this in the following way:

Adding a working example with index data, mapping, search query, and search result

Index Mapping:

{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer": {
          "tokenizer": "my_tokenizer"
        }
      },
      "tokenizer": {
        "my_tokenizer": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 20,
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      }
    },
    "max_ngram_diff": 50
  },
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "my_analyzer"
      }
    }
  }
}

Index Data:

{
    "name":"EVA新世纪福音战士"
}

Search Query:

{
  "query": {
    "match": {
      "name": {
        "query": "EV"
      }
    }
  },
  "highlight": {
    "fields": {
      "*": {
        "type": "plain",
        "fragment_size": 20,
        "pre_tags": "<span class='bold'>",
        "post_tags": "</span>",
        "number_of_fragments": 1
      }
    }
  }
}

Search Result:

"hits": [
  {
    "_index": "65821975",
    "_type": "_doc",
    "_id": "1",
    "_score": 0.5753642,
    "_source": {
      "name": "EVA新世纪福音战士"
    },
    "highlight": {
      "name": [
        "<span class='bold'>EV</span>A新世纪福音战士"
      ]
    }
  }
]
Related