# Compound word token filter: only\_longest\_match doesn't work as expected in some scenarios

**URL:** https://discuss.elastic.co/t/compound-word-token-filter-only-longest-match-doesnt-work-as-expected-in-some-scenarios/195470
**Category:** Elasticsearch
**Created:** [August 16, 2019, 10:11am UTC](https://discuss.elastic.co/t/compound-word-token-filter-only-longest-match-doesnt-work-as-expected-in-some-scenarios/195470 "2019-08-16T10:11:51Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![andrebarthelmes](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/andrebarthelmes/32/63094_2.png) [@andrebarthelmes](https://discuss.elastic.co/u/andrebarthelmes)
#### Post date: [August 16, 2019, 10:11am UTC](https://discuss.elastic.co/t/compound-word-token-filter-only-longest-match-doesnt-work-as-expected-in-some-scenarios/195470/1 "2019-08-16T10:11:51Z")

</div>

Hi,

I work on a german product search. To make things more clear I "translated" my problem to the following case:

lets assume I have four documents each containing one of the following words in my index:

"starlight"  
"moonlight"  
"lighthouse"  
"lightbulb"

If I search now for "light", I of course won't find any.

So I define two (identical) analyzers that are used for the respective field for indexation and search. These analyzers only consists of a "dictionary\_decompounder" with the "word\_list" : ["light"].

So now of course I will find all 4 documents. If I now like to exclude "lightbulb" and "starlight" from the "light" search results, I add these two words to the "word\_list" : ["light","lightbulb","starlight"] and activate "only\_longest\_match": "true".

Now I would expect only the "moonlight" and "lighthouse" documents if I search for "light" again.

Weirdly the "lightbulb" disappears as desired now, but I still get the "starlight" document returned (in addition to the expected "moonlight" and "lighthouse" documents).

This seems to be the case because in "lightbulb" "light" is at the start of the word, where in "starlight" it's at the end.

Does anyone have any idea how I can ensure that "starlight" doesn't show up when I search for "light" in this scenario?

Thanks

---

<div class="post-metadata">

### Author: ![abdon](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/abdon/32/9195_2.png) [@abdon](https://discuss.elastic.co/u/abdon)
#### Post date: [August 19, 2019, 11:34am UTC](https://discuss.elastic.co/t/compound-word-token-filter-only-longest-match-doesnt-work-as-expected-in-some-scenarios/195470/2 "2019-08-19T11:34:09Z")

</div>

The `only_longest_match` option may not quite work how you think it does. [This Lucene issue comment](https://issues.apache.org/jira/browse/LUCENE-8183?focusedCommentId=16374886&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-16374886) has details on how it works:

> The onlyLongestMatch flag currently affects whether all matches or only the longest match should be returned **per**** start**character (in DictionaryCompoundWordTokenFilter) or**per **hyphenation** start** point (in HyphenationCompoundWordTokenFilter).
> 
> Example:  
> Dictionary "Schaft", "Wirt", "Wirtschaft", "Wissen", "Wissenschaft" for input "Wirtschaftswissenschaft" will return the original input plus tokens "Wirtschaft", "schaft", "wissenschaft", "schaft" but not "Wirt" or "Wissen". "schaft" is still returned (even twice) because it's the longest token starting at the respective position.

So, I don't think `only_longest_match` is the way to go here.

One way to prevent certain words from being decompounded is by mapping those words to some "placeholder tokens" that do not get decompounded. The [mapping character filter](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-mapping-charfilter.html) could be used for that. For example, you could create your index like this:

```auto
PUT my_index
{
  "settings": {
    "analysis": {
      "char_filter": {
        "my_char_filter": {
          "type": "mapping",
          "mappings": [
            "lightbulb => DO_NOT_DECOMPOUND_1",
            "starlight => DO_NOT_DECOMPOUND_2"
          ]
        }
      },
      "filter": {
        "my_decompounder": {
          "type": "dictionary_decompounder",
          "word_list": [
            "light"
          ]
        }
      },
      "analyzer": {
        "my_analyzer": {
          "char_filter": ["my_char_filter"],
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "my_decompounder"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "my_field": {
        "type": "text",
        "analyzer": "my_analyzer"
      }
    }
  }
}

```

The character filter will prevent `lightbulb` and `starlight` from being decompounded by replacing those words by `DO_NOT_DECOMPOUND_1` and `DO_NOT_DECOMPOUND_2`. You can see how this works by testing the `my_analyzer` analyzer on `lighthouse` and `lightbulb`:

```auto
GET my_index/_analyze
{
  "analyzer" : "my_analyzer",
  "text" : "lighthouse"
}

GET my_index/_analyze
{
  "analyzer" : "my_analyzer",
  "text" : "lightbulb"
}

```

You will see that `lighthouse` does get a token `light`, but `lightbulb` does not. And you can test that it works as desired in queries like this:

```auto
PUT my_index/_doc/1
{
  "my_field": "lightbulb"
}

PUT my_index/_doc/2
{
  "my_field": "lighthouse"
}

GET my_index/_search
{
  "query": {
    "match": {
      "my_field": "light"
    }
  }
}

```

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)
#### Post date: [September 16, 2019, 11:41am UTC](https://discuss.elastic.co/t/compound-word-token-filter-only-longest-match-doesnt-work-as-expected-in-some-scenarios/195470/3 "2019-09-16T11:41:25Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
