# Synonym Token Filter questions

**URL:** <https://discuss.elastic.co/t/synonym-token-filter-questions/196705>\
**Category:** Elasticsearch\
**Created:** [August 26, 2019, 5:26am UTC](https://discuss.elastic.co/t/synonym-token-filter-questions/196705 "2019-08-26T05:26:18Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![jjarthur](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jjarthur/32/48545_2.png) [@jjarthur](https://discuss.elastic.co/u/jjarthur)\
**Post date:** [August 26, 2019, 5:26am UTC](https://discuss.elastic.co/t/synonym-token-filter-questions/196705/1 "2019-08-26T05:26:18Z")

</div>

I am attempting to implement synonyms into my search and ran into a couple of questions.

1. Firstly, I have a synonyms.txt file with the following mappings:

2. Separately, I also have some trouble with multi-word synonyms. I have a synonyms.txt file with the following mappings:

Any help is greatly appreciated -- cheers!

---

<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 26, 2019, 8:07am UTC](https://discuss.elastic.co/t/synonym-token-filter-questions/196705/2 "2019-08-26T08:07:22Z")

</div>

To get exact matches ranked higher than synonym matches you need write a query that searches with and without synonyms at the same time. For example a `bool` query like this:

```auto
GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "my_field": "baz"
          }
        }
      ],
      "should": [
        {
          "match": {
            "my_field": {
              "query": "baz",
              "analyzer": "standard"
            }
          }
        }
      ]
    }
  }
}

```

The idea of the query above is that the optional `should` clause will only match exact hits, because it overrides the search analyzer. Documents that match this `should` clause will get a higher score.

If you want to search for phrases, then that is something you would not necessarily achieve with an analyzer. Take a look at using [the `match_phrase` query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query-phrase.html) instead. If you do want to go with an analyzer then check out [this blog post](https://opensourceconnections.com/blog/2016/12/02/solr-elasticsearch-synonyms-better-patterns-keyphrases/) for a useful pattern.

By the way, I see you are using the `synonym` filter. With multi-word synonyms, [the `synonym_graph` filter](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-synonym-graph-tokenfilter.html) will work better. You may want to switch to that filter.

---

<div class="post-metadata">

**Author:** ![jjarthur](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jjarthur/32/48545_2.png) [@jjarthur](https://discuss.elastic.co/u/jjarthur)\
**Post date:** [August 27, 2019, 1:40am UTC](https://discuss.elastic.co/t/synonym-token-filter-questions/196705/3 "2019-08-27T01:40:34Z")

</div>

Thanks for the resources @abdon. The biggest thing I was missing was using `match_phrase` instead of just `match`. This looks like it almost solves the problem on its own. I have also swapped to `synonym_graph` as it seems to fit my use-case better. I'll post back if I run into any more issues.

---

<div class="post-metadata">

**Author:** ![jjarthur](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jjarthur/32/48545_2.png) [@jjarthur](https://discuss.elastic.co/u/jjarthur)\
**Post date:** [August 27, 2019, 3:58am UTC](https://discuss.elastic.co/t/synonym-token-filter-questions/196705/4 "2019-08-27T03:58:53Z")

</div>

Okay, maybe jumped the gun a bit here. `match_phrase` works great for synonyms that are acronyms because it stops the tokenizing of each word in the query. Unfortunately however, it also stops tokenizing all other queries that do not have a synonym. Is there a simple way to have the `match_phrase` functionality apply only when a synonym is found?

---

<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 27, 2019, 7:42am UTC](https://discuss.elastic.co/t/synonym-token-filter-questions/196705/5 "2019-08-27T07:42:51Z")

</div>

Did you read [this blog post](https://opensourceconnections.com/blog/2016/12/02/solr-elasticsearch-synonyms-better-patterns-keyphrases/) that I shared in my earlier post? I think it covers exactly what you want to do.

---

<div class="post-metadata">

**Author:** ![jjarthur](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jjarthur/32/48545_2.png) [@jjarthur](https://discuss.elastic.co/u/jjarthur)\
**Post date:** [August 27, 2019, 10:01pm UTC](https://discuss.elastic.co/t/synonym-token-filter-questions/196705/6 "2019-08-27T22:01:32Z")

</div>

Sorry, yes I did. It seems to be a bit outdated (filters no longer support a 'tokenizer' field), but I was going to attempt to use one of the methods described today.

---

<div class="post-metadata">

**Author:** ![jjarthur](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jjarthur/32/48545_2.png) [@jjarthur](https://discuss.elastic.co/u/jjarthur)\
**Post date:** [August 27, 2019, 11:42pm UTC](https://discuss.elastic.co/t/synonym-token-filter-questions/196705/7 "2019-08-27T23:42:09Z")

</div>

I believe I have solved this for now using 'Autophrase with synonym step' in the linked blog post. My settings looks something like this:

```
    "analysis": {
        "analyzer": {
            "synonym": {
                "tokenizer": "standard",
                "filter": ["lowercase", "autophrase_synonym", "synonym"]
            }
        },
        "filter": {
            "autophrase_synonym": {
                "type": "synonym",
                "synonyms": [
                  "internet corporation for assigned names and numbers => internet_corporation_for_assigned_names_and_numbers"
                ]
            },
            "synonym": {
                "type": "synonym",
                "synonyms": [
                    "internet_corporation_for_assigned_names_and_numbers, icann", "foo, bar, baz"
                ]
            }
        }
    }
```

---

<div class="post-metadata">

**Author:** ![jjarthur](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jjarthur/32/48545_2.png) [@jjarthur](https://discuss.elastic.co/u/jjarthur)\
**Post date:** [August 28, 2019, 1:28am UTC](https://discuss.elastic.co/t/synonym-token-filter-questions/196705/8 "2019-08-28T01:28:35Z")

</div>

I tried your `bool` query idea posted above in order to rank exact matches higher in the results. The results returned a higher score for every entry, which leads to no changes in the rankings overall. I believe this is because my synonym filter needs to run on the index analyzer as well as the search analyzer.

Is there another approach I can take or any way around this that you are aware of?

---

<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 28, 2019, 7:32am UTC](https://discuss.elastic.co/t/synonym-token-filter-questions/196705/9 "2019-08-28T07:32:00Z")

</div>

You can use [multi-fields](https://www.elastic.co/guide/en/elasticsearch/reference/current/multi-fields.html) to index your data twice: once with synonyms (using your synonym analyzer), and once without (using the standard analyzer). [The docs have an example](https://www.elastic.co/guide/en/elasticsearch/reference/current/multi-fields.html#_multi_fields_with_multiple_analyzers) on how to do this.

In your `bool` query's `must` clause you can then query the field with synonyms, and in the `should` clause the field without synonyms.

---

<div class="post-metadata">

**Author:** ![jjarthur](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jjarthur/32/48545_2.png) [@jjarthur](https://discuss.elastic.co/u/jjarthur)\
**Post date:** [August 29, 2019, 5:04am UTC](https://discuss.elastic.co/t/synonym-token-filter-questions/196705/10 "2019-08-29T05:04:43Z")

</div>

This works very well. Thank you @abdon.

---

<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 26, 2019, 5:04am UTC](https://discuss.elastic.co/t/synonym-token-filter-questions/196705/11 "2019-09-26T05:04:57Z")

</div>

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