# Busca por palavras incompletas

**URL:** <https://discuss.elastic.co/t/busca-por-palavras-incompletas/196547>\
**Category:** Elastic em Português - Brasil\
**Created:** [August 23, 2019, 2:30pm UTC](https://discuss.elastic.co/t/busca-por-palavras-incompletas/196547 "2019-08-23T14:30:05Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Jonathan\_Marfil](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/jonathan_marfil/32/52857_2.png) [@Jonathan\_Marfil](https://discuss.elastic.co/u/Jonathan_Marfil)\
**Post date:** [August 23, 2019, 2:30pm UTC](https://discuss.elastic.co/t/busca-por-palavras-incompletas/196547/1 "2019-08-23T14:30:06Z")

</div>

Bom dia pessoal.

Preciso de ajuda.

Sou novo no ElasticSearch e estou com um problema.

Supondo que eu tenha um índice de filmes, e um dos meus campos é a Sinopse do Filme, por exemplo, a Capitã Marvel:

"Carol Danvers (Brie Larson) é uma ex-agente da Força Aérea norte-americana, que, sem se lembrar de sua vida na Terra, é recrutada pelos Kree para fazer parte de seu exército de elite. Inimiga declarada dos Skrull, ela acaba voltando ao seu planeta de origem para impedir uma invasão dos metaformos, e assim vai acabar descobrindo a verdade sobre si, com a ajuda do agente Nick Fury (Samuel L. Jackson) e da gata Goose."

Se eu precisar buscar nesse campo com palavras incompletas, por exemplo, que o usuário se lembre que há algo com "america" (que na verdade é americana) e cita algo como "formo" (que são metaformos).

Qual a melhor de maneira de fazer essa busca com mais de uma palavra incompleta?

Agradeço a quem puder ajudar.

---

<div class="post-metadata">

**Author:** ![luiz.santos](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/luiz.santos/32/24664_2.png) [@luiz.santos](https://discuss.elastic.co/u/luiz.santos)\
**Post date:** [September 3, 2019, 1:30pm UTC](https://discuss.elastic.co/t/busca-por-palavras-incompletas/196547/2 "2019-09-03T13:30:16Z")

</div>

Oi @Jonathan_Marfil,

Uma forma de conseguir esse resultado é utilizando [NGrams](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-ngram-tokenizer.html). Para isso, você precisa criar um analyzer customizado e mapear o campo para utilizar esse analyzer. Um detalhe importante é que para melhorar a precisão dos resultados vamos utilizar um analyzer de indexação diferente do analyzer de consulta. Veja a seguir:

```auto
PUT /ngram-test
{
  "settings": {
    "index.max_ngram_diff": 15,
    "analysis": {
      "filter": {
        "like_filter": {
          "type": "ngram",
          "min_gram": 3,
          "max_gram": 18,
          "token_chars": [
            "letter",
            "digit"
          ]
        }
      },
      "analyzer": {
        "like_analyzer": {
          "type": "custom",
          "tokenizer": "keyword",
          "filter": [
            "lowercase",
            "like_filter"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "sinopse": {
        "analyzer": "like_analyzer",
        "search_analyzer": "standard", 
        "type": "text"
      }
    }
  }
}

```

Agora basta indexar o documento e fazer a busca:

```auto
PUT ngram-test/_doc/1
{
  "sinopse": "Carol Danvers (Brie Larson) é uma ex-agente da Força Aérea norte-americana, que, sem se lembrar de sua vida na Terra, é recrutada pelos Kree para fazer parte de seu exército de elite. Inimiga declarada dos Skrull, ela acaba voltando ao seu planeta de origem para impedir uma invasão dos metaformos, e assim vai acabar descobrindo a verdade sobre si, com a ajuda do agente Nick Fury (Samuel L. Jackson) e da gata Goose."
}

GET ngram-test/_search
{
  "query": {
    "match": {
      "sinopse": {
        "query": "formos"
      }
    }
  }
}

```

Resultado:

```auto
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.48679504,
    "hits" : [
      {
        "_index" : "ngram-test",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.48679504,
        "_source" : {
          "sinopse" : "Carol Danvers (Brie Larson) é uma ex-agente da Força Aérea norte-americana, que, sem se lembrar de sua vida na Terra, é recrutada pelos Kree para fazer parte de seu exército de elite. Inimiga declarada dos Skrull, ela acaba voltando ao seu planeta de origem para impedir uma invasão dos metaformos, e assim vai acabar descobrindo a verdade sobre si, com a ajuda do agente Nick Fury (Samuel L. Jackson) e da gata Goose."
        }
      }
    ]
  }
}

```

Alguns ressalvas **importantes** :

- Ao utilizar o filter ngram é esperado que o índice ocupe muito espaço em disco uma vez que a quantidade de tokens produzido é muito maior;
- Quanto maior a diferença entre min\_gram e max\_gram, maior será o espaço em disco utilizado;
- Ao mesmo tempo se o max\_gram for 18 e o termo digitado pelo usuário for maior que 18 o documento não será achado, é um trade-off;
- Dependendo do tamanho da sua base de documentos essa estratégia pode ser inviável;

Recomendo a leitura de um [post](https://medium.com/@ashishstiwari/what-should-be-the-value-of-max-gram-and-min-gram-in-elasticsearch-f091404c9a14) com algumas discussões interessantes sobre o tema.

Abraço,  
Luiz Guilherme

---

<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:** [November 4, 2022, 7:22am UTC](https://discuss.elastic.co/t/busca-por-palavras-incompletas/196547/3 "2022-11-04T07:22:39Z")

</div>


