# Want to do partial match without using wildcards

**URL:** <https://discuss.elastic.co/t/want-to-do-partial-match-without-using-wildcards/362928>\
**Category:** Elasticsearch\
**Created:** [July 11, 2024, 4:32am UTC](https://discuss.elastic.co/t/want-to-do-partial-match-without-using-wildcards/362928 "2024-07-11T04:32:40Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![PratikStar](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/pratikstar/32/135965_2.png) [@PratikStar](https://discuss.elastic.co/u/PratikStar)\
**Post date:** [July 11, 2024, 4:32am UTC](https://discuss.elastic.co/t/want-to-do-partial-match-without-using-wildcards/362928/1 "2024-07-11T04:32:40Z")

</div>

I want to do a partial match on text fields (these fields include Japanese text data, but more on that later, I want to nail the core functionality correctly before going into Japanese.) without using wildcards.

Here are some example matches I need:  
 --\> [results]

- "beatl" --\> ["beatles", "beatl", ...]
- "ance" --\> ["dance", "chance", ...]
- "bieb" --\> ["Bieber", "Doobie Brothers", ...]

**My experiments with wildcards:**

- I made the fields non-analyzed and used wildcard queries.
- The performance was abysmal Since the queries I wrote included a leading asterisk (my data size is 70 million+ documents).
- And over that I need to use `multi_match` over a set of text fields, So in all wildcards did not work.

**My experiments with ngrams:**

- I used min and max-gram = 3, and tested. Below are the bad results that I don't want to show up.
- "Beatl" --\> ["atlas beaz feat", ...] (I could understand why this showed up. It was since it contained all the 3-grams from Beatl, But I don't want such results)

**Some thoughts to improve with the n-gram search situation:**

- I wonder if I can do a post filter after receiving the results from Ngram. using wildcards here may not be as expensive.
- Can I give a higher rating (or filtering) to n-grams that are overlapping? So that results like "Atlas Beaz feat" will not show up.

Is there any other way to make partial match possible?

Here is my index settings with n-grams.

```auto
"settings":{
      "analysis":{
        "char_filter":{
          "remove_spaces": {
            "type": "pattern_replace",
            "pattern": "(\\s)",
            "replacement": ""
          }
        },
        "tokenizer":{
          "eng_ngram_tokenizer": {
            "type": "ngram",
            "min_gram": 3,
            "max_gram": 3,
            "token_chars": [
              "letter",
              "digit",
              "punctuation",
              "symbol"
            ],
            "custom_token_chars": ["~","[","]","・"]
          }
        },
        "filter":{
          "custom_asciifolding":{
            "type":"asciifolding",
            "preserve_original":true
          }
        },
        "analyzer":{
          "eng_ngram_analyzer": {
            "type": "custom",
            "char_filter": [
              "remove_spaces"
            ],
            "tokenizer": "eng_ngram_tokenizer",
            "filter": [
              "lowercase",
              "custom_asciifolding"
            ]
          }
        }
      }
    },
...

```

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [July 11, 2024, 5:05am UTC](https://discuss.elastic.co/t/want-to-do-partial-match-without-using-wildcards/362928/2 "2024-07-11T05:05:59Z")

</div>

Welcome!

When using ngrams, you want to apply them at index time but not on search time! Not on the query.

For that you need to tell Elasticsearch to use a simple analyzer at search time. See [search\_analyzer | Elasticsearch Guide [8.14] | Elastic](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-analyzer.html)

---

<div class="post-metadata">

**Author:** ![PratikStar](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/pratikstar/32/135965_2.png) [@PratikStar](https://discuss.elastic.co/u/PratikStar)\
**Post date:** [July 11, 2024, 6:41am UTC](https://discuss.elastic.co/t/want-to-do-partial-match-without-using-wildcards/362928/3 "2024-07-11T06:41:29Z")

</div>

@dadoonet Thanks for your response. Appreciate it 🙏 !

So I tried using my custom ngram analyzer for index time. And standard analyzer (with the filters I am applying in index time analyzer) in search time.

\*\*This is my search time analyzer: \*\*

```auto
...
          "eng_search_analyzer": {
            "type": "custom",
            "char_filter": [
              "remove_spaces"
            ],
            "tokenizer": "standard",
            "filter": [
              "lowercase",
              "custom_asciifolding"
            ]
          }
...

```

(Refer to the question for the definitions of filter and char\_filter)

But I saw no results, and my understanding is that's because I need to increase the max\_gram to a higher value, the search query is not tokenized anymore.

I somehow feel it is not a good choice to do something like `min_gram: 2 and max_gram: 20` on my data with 70 million, but please advice me if this is a commonly accepted practice.

Thanks,  
Pratik

---

<div class="post-metadata">

**Author:** ![Mark\_Harwood1](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/mark_harwood1/32/101255_2.png) [@Mark\_Harwood1](https://discuss.elastic.co/u/Mark_Harwood1)\
**Post date:** [July 11, 2024, 7:16am UTC](https://discuss.elastic.co/t/want-to-do-partial-match-without-using-wildcards/362928/4 "2024-07-11T07:16:38Z")

</div>

Elasticsearch has a special field type that uses ngrams to accelerate wildcard and regex queries: [Find strings within strings faster with the Elasticsearch wildcard field | Elastic Blog](https://www.elastic.co/blog/find-strings-within-strings-faster-with-the-new-elasticsearch-wildcard-field)

---

<div class="post-metadata">

**Author:** ![PratikStar](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/pratikstar/32/135965_2.png) [@PratikStar](https://discuss.elastic.co/u/PratikStar)\
**Post date:** [July 11, 2024, 7:56am UTC](https://discuss.elastic.co/t/want-to-do-partial-match-without-using-wildcards/362928/5 "2024-07-11T07:56:00Z")

</div>

@Mark_Harwood1 This looks promising. I will try this out.  
Thanks a lot.

---

<div class="post-metadata">

**Author:** ![dadoonet](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dadoonet/32/137187_2.png) [@dadoonet](https://discuss.elastic.co/u/dadoonet)\
**Post date:** [July 11, 2024, 10:33am UTC](https://discuss.elastic.co/t/want-to-do-partial-match-without-using-wildcards/362928/6 "2024-07-11T10:33:00Z")

</div>

If you don't succeed, the best thing to do is to create a full reproduction script so we can play with it in Kibana and propose concrete fixes. 🙂
