이미 synonym filter 테스트 관련 글을 공유 했었습니다.
- [Elasticsearch] Synonym filter 테스트
이 테스트에서 발생한 문제는 동의어에 대한 position 정보가 잘 못되는 것입니다.
테스트 환경은 기본 Elasticsearch 6.x 에서 진행 되었습니다. 
아래는 SynonymFilter 코드 내 주석 입니다.
[SynonymFilter.java]
 Matches single or multi word synonyms in a token stream.
 This token stream cannot properly handle position
 increments != 1, ie, you should place this filter before
 filtering out stop words.
그리고 아래는 동의어 처리 시 문제가 발생 하는 부분의 코드 입니다.
[SynonymMap.java]
 /** Sugar: analyzes the text with the analyzer and
 *  separates by {@link SynonymMap#WORD_SEPARATOR}.
 *  reuse and its chars must not be null. */
public CharsRef analyze(String text, CharsRefBuilder reuse) throws IOException {
  try (TokenStream ts = analyzer.tokenStream("", text)) {
    CharTermAttribute termAtt = ts.addAttribute(CharTermAttribute.class);
    PositionIncrementAttribute posIncAtt = ts.addAttribute(PositionIncrementAttribute.class);
    ts.reset();
    reuse.clear();
    while (ts.incrementToken()) {
      int length = termAtt.length();
      if (length == 0) {
        throw new IllegalArgumentException("term: " + text + " analyzed to a zero-length token");
      }
      if (posIncAtt.getPositionIncrement() != 1) {
        throw new IllegalArgumentException("term: " + text + " analyzed to a token (" + termAtt +
                                           ") with position increment != 1 (got: " + posIncAtt.getPositionIncrement() + ")");
      }
      reuse.grow(reuse.length() + length + 1); /* current + word + separator */
      int end = reuse.length();
      if (reuse.length() > 0) {
        reuse.setCharAt(end++, SynonymMap.WORD_SEPARATOR);
        reuse.setLength(reuse.length() + 1);
      }
      System.arraycopy(termAtt.buffer(), 0, reuse.chars(), end, length);
      reuse.setLength(reuse.length() + length);
    }
    ts.end();
  }
  if (reuse.length() == 0) {
    throw new IllegalArgumentException("term: " + text + " was completely eliminated by analyzer");
  }
  return reuse.get();
}
기본적으로 동의어 처리에 대한 문제는 이미 lucene 레벨에서 개선이 되었습니다.
관련 참고 링크는 아래와 같습니다.
[Reference links]
https://issues.apache.org/jira/browse/LUCENE-6664
http://blog.mikemccandless.com/2012/04/lucenes-tokenstreams-are-actually.html
이와 같이 개선된 synonym filter 를 elasticsearch 에서는 아래와 같이 사용 할 수 있습니다.
[Reference links]
https://www.elastic.co/guide/en/elasticsearch/reference/master/analysis-synonym-graph-tokenfilter.html
[Create index]
PUT /syngtest
{
  "settings": {
    "index.number_of_shards": 1,
    "index.number_of_replicas": 0,
    "index": {
      "analysis": {
        "analyzer": {
          "arirang_custom": {
            "tokenizer": "arirang_tokenizer",
            "filter": [
              "lowercase",
              "trim",
              "arirang_filter",
              "custom_synonym"
            ]
          }
        },
        "filter": {
          "custom_synonym": {
            "type": "synonym_graph",
            "synonyms": [
              "henry,헨리,앙리",
              "신해철,마왕"
            ]
          }
        }
      }
    }
  }
}
[Request analyze]
GET /syngtest/_analyze
{
  "tokenizer": "arirang_tokenizer",
  "filter": [
    "lowercase",
    "trim",
    "arirang_filter",
    "custom_synonym"
  ],
  "text": "신해철은 henry"
}
[Analyzed result]
{
  "tokens": [
    {
      "token": "마왕",
      "start_offset": 0,
      "end_offset": 3,
      "type": "SYNONYM",
      "position": 0
    },
    {
      "token": "신해철",
      "start_offset": 0,
      "end_offset": 3,
      "type": "korean",
      "position": 0
    },
    {
      "token": "헨리",
      "start_offset": 5,
      "end_offset": 10,
      "type": "SYNONYM",
      "position": 1
    },
    {
      "token": "앙리",
      "start_offset": 5,
      "end_offset": 10,
      "type": "SYNONYM",
      "position": 1
    },
    {
      "token": "henry",
      "start_offset": 5,
      "end_offset": 10,
      "type": "word",
      "position": 1
    }
  ]
}
특별히 코드를 수정 하거나 하지 않고 문제가 해결 된 것을 확인 하실 수 있습니다.
왜 해결 되었는지는 위 synonym graph filter 에 대해서 문서를 보시면 되겠습니다.