Skip to content

06 ‐ Index Settings: Entendendo Mapping, Analyzers e Aliases

inhogoes edited this page May 8, 2026 · 1 revision

6.1 - Mapping

O mapping define como os campos de um documento são armazenados e indexados no Elasticsearch. É equivalente ao schema de uma tabela em um banco de dados relacional — mas com diferenças importantes: no Elasticsearch, o mapping pode ser definido explicitamente antes da indexação ou inferido automaticamente pelo próprio Elasticsearch ao receber o primeiro documento.

Definir o mapping explicitamente é uma boa prática em ambientes de produção. Sem isso, o Elasticsearch pode inferir tipos incorretos — por exemplo, tratar um campo de CEP como long em vez de keyword — e o mapping não pode ser alterado depois que os dados já foram indexados. Para mudar o tipo de um campo, é necessário reindexar os dados.

Tipos de campo (Field Data Types)

Os tipos mais usados no dia a dia:

Tipo Uso típico Exemplo de valor
text Texto livre — será analisado (tokenizado) para full-text search "Produto de alta qualidade"
keyword Valores exatos — usado para filtros, ordenação e agregações (ex: status, UF, ID) "SP", "ativo", "CA-2024-001"
integer Números inteiros de 32 bits. Faixa: -2.147.483.648 a 2.147.483.647 42, -10, 2024 (idade, ano, quantidade)
long Números inteiros de 64 bits. Faixa muito maior que integer 1704067200000 (timestamps Unix em milissegundos, IDs grandes)
double Números decimais de 64 bits (alta precisão) 19.99, -0.5, 3.14159 (preços, coordenadas, taxas)
float Números decimais de 32 bits (menor precisão, ocupa menos espaço) 1.5, 98.6 (métricas de sistema, onde precisão absoluta não é crítica)
byte Inteiro de 8 bits. Faixa: -128 a 127 42 (flags, níveis de prioridade com poucos valores)
short Inteiro de 16 bits. Faixa: -32.768 a 32.767 1000 (portas de rede, códigos pequenos)
date Datas e timestamps "2024-05-01", "2024-05-01T10:30:00Z"
boolean Verdadeiro ou falso true, false
geo_point Coordenadas geográficas (latitude/longitude) "-23.5505, -46.6333"
nested Arrays de objetos com relacionamento interno preservado Lista de itens de um pedido, cada um com nome e preço
object Objeto JSON aninhado { "rua": "Av. Brasil", "numero": 100 }

Dica prática: na dúvida entre integer e long, prefira long — o custo de armazenamento é pequeno e evita problemas de overflow em campos que podem crescer. Entre float e double, use double para valores financeiros onde precisão importa, e float apenas em métricas de monitoramento onde uma pequena perda de precisão é aceitável.

Exemplo de mapping explícito

PUT /clientes
{
  "mappings": {
    "properties": {
      "nome":  { "type": "text" },
      "idade": { "type": "integer" },
      "email": { "type": "keyword" }
    }
  }
}

Multi-fields

É possível indexar o mesmo campo com dois tipos diferentes usando fields. Isso é útil quando você precisa tanto de full-text search quanto de filtros/ordenação no mesmo campo:

PUT /clientes
{
  "mappings": {
    "properties": {
      "nome": {
        "type": "text",
        "fields": {
          "raw": {
            "type": "keyword"
          }
        }
      }
    }
  }
}

Nesse exemplo, nome é indexado como text (para buscas por texto) e nome.raw como keyword (para ordenação e agregações exatas).

Meta Fields

Todo documento no Elasticsearch possui, além dos campos definidos pelo usuário, um conjunto de campos especiais chamados meta fields. Eles são gerados e mantidos pelo próprio Elasticsearch e fornecem informações sobre o documento em si.

Os meta fields mais relevantes no dia a dia:

Meta field O que contém
_id Identificador único do documento dentro do índice. Pode ser definido na indexação ou gerado automaticamente pelo Elasticsearch.
_index Nome do índice ao qual o documento pertence.
_source O conteúdo JSON original do documento, exatamente como foi indexado. É o que aparece nos resultados de busca. Pode ser desabilitado para economizar espaço, mas aí o documento não pode ser recuperado na íntegra.
_routing Controla em qual shard o documento é armazenado. Por padrão, é calculado com base no _id. Pode ser customizado para garantir que documentos relacionados fiquem no mesmo shard.
_meta Campo livre para armazenar metadados sobre o mapping — como versão, descrição ou informações de governança. Não é usado pelo Elasticsearch na busca.
_seq_no Número de sequência do documento — incrementado a cada operação de escrita. Usado para controle de concorrência otimista.
_primary_term Junto com _seq_no, identifica unicamente uma versão do documento. Útil para operações condicionais de update e delete.

Exemplo: recuperar um documento e observar seus meta fields:

GET /clientes/_doc/1

A resposta inclui _id, _index, _seq_no, _primary_term e o _source com os dados do documento.

Exemplo: desabilitar o _source (use com cautela — o documento não poderá ser recuperado na íntegra):

PUT /metricas
{
  "mappings": {
    "_source": {
      "enabled": false
    }
  }
}

Parâmetros de mapeamento

Além do type, cada campo pode receber parâmetros adicionais que controlam como ele é indexado e armazenado:

Parâmetro Aplica a O que faz
index Todos Se false, o campo é armazenado no _source mas não é indexado — não pode ser usado em buscas ou filtros. Útil para campos grandes que só precisam ser recuperados, não filtrados.
store Todos Se true, o campo é armazenado separadamente do _source. Raramente necessário — o _source já permite recuperar qualquer campo.
doc_values keyword, numéricos, datas Estrutura de dados em disco usada para ordenação e agregações. Habilitado por padrão nesses tipos. Desabilitar economiza disco mas remove a capacidade de ordenar e agregar pelo campo.
norms text Informações de comprimento do campo usadas no cálculo de score. Desabilitar ("norms": false) economiza memória em campos que são usados apenas como filtros, não para busca por relevância.
copy_to Todos Copia o valor do campo para outro campo virtual, permitindo fazer buscas em múltiplos campos como se fossem um só.
fields Todos Define sub-campos com tipos ou analyzers diferentes — o multi-field descrito acima.
null_value keyword, numéricos Define um valor substituto para indexar quando o campo for null. Sem isso, campos nulos não são indexados e não aparecem em filtros.
eager_global_ordinals keyword Pré-carrega os ordinals globais na memória ao reabrir o índice. Melhora o desempenho de agregações terms em campos de alta cardinalidade que são consultados com muita frequência.

Exemplo combinando parâmetros:

PUT /pedidos
{
  "mappings": {
    "properties": {
      "descricao": {
        "type": "text",
        "norms": false,
        "copy_to": "busca_geral"
      },
      "status": {
        "type": "keyword",
        "null_value": "desconhecido"
      },
      "valor_bruto": {
        "type": "double",
        "index": false
      },
      "busca_geral": {
        "type": "text"
      }
    }
  }
}

Nesse exemplo: descricao não usa norms (economiza memória); status indexa o valor "desconhecido" quando o campo vier nulo; valor_bruto é armazenado mas não indexado (só para recuperação); e o campo virtual busca_geral recebe cópias de outros campos para buscas combinadas.

Mapeamento dinâmico (Dynamic Mapping)

Quando nenhum mapping é definido, o Elasticsearch infere os tipos automaticamente ao indexar o primeiro documento:

POST /clientes/_doc/1
{
  "nome":  "Maria",
  "idade": 28
}

O Elasticsearch inferirá nome como text (com subcampo keyword automático) e idade como long.

O comportamento do mapeamento dinâmico é controlado pelo parâmetro dynamic, com três valores possíveis:

Valor Comportamento
true (padrão) Novos campos são detectados e adicionados ao mapping automaticamente
false Novos campos são aceitos e armazenados no _source, mas não são indexados — não podem ser pesquisados
strict Documentos com campos não mapeados são rejeitados com erro

Exemplo com dynamic: strict:

PUT /clientes
{
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "codigo": { "type": "integer" },
      "nome":   { "type": "text" }
    }
  }
}

Com essa configuração, qualquer documento que contenha campos além de codigo e nome será rejeitado pelo Elasticsearch.

Dynamic Templates

Permitem definir regras de mapeamento para campos novos com base em padrões de nome ou tipo. São aplicadas somente quando o mapeamento dinâmico está ativo e um campo novo é encontrado.

Exemplo — todos os campos do tipo string que comecem com logradouro devem ser indexados como keyword:

PUT /clientes
{
  "mappings": {
    "dynamic_templates": [
      {
        "logradouros_as_keywords": {
          "match_mapping_type": "string",
          "match_pattern": "regex",
          "match": "^logradouro.*",
          "mapping": {
            "type": "keyword"
          }
        }
      }
    ]
  }
}

Outro exemplo comum — tratar todos os campos de string como keyword por padrão:

PUT /clientes
{
  "mappings": {
    "dynamic_templates": [
      {
        "strings_as_keywords": {
          "match_mapping_type": "string",
          "mapping": {
            "type": "keyword"
          }
        }
      }
    ]
  }
}

6.2 - Analysis: Analyzers, Tokenizers e Filters

A análise de texto é o processo que o Elasticsearch aplica sobre campos do tipo text no momento da indexação e da busca. Ela transforma o texto bruto em uma lista de termos (tokens) que serão armazenados no índice invertido.

Analysis Elastic

Componentes de um Analyzer

Um analyzer é composto por três partes, aplicadas em sequência:

Analyzers Elastic

  1. Character Filters: processam o texto bruto antes da tokenização. Podem remover ou substituir caracteres — por exemplo, remover tags HTML ou converter & em and.

  2. Tokenizer: divide o texto em tokens. O tokenizer standard divide por espaços e pontuação, removendo a pontuação dos tokens resultantes. Cada analyzer tem exatamente um tokenizer.

  3. Token Filters: processam cada token gerado pelo tokenizer. Podem converter para minúsculas (lowercase), remover stopwords (stop), aplicar stemming, adicionar sinônimos, entre outros.

Analyzers built-in

O Elasticsearch vem com vários analyzers prontos para uso:

Analyzer O que faz
standard Tokeniza por espaços e pontuação, converte para minúsculas. É o padrão para campos text.
simple Tokeniza por qualquer caractere não-letra, converte para minúsculas
whitespace Tokeniza apenas por espaços — preserva pontuação
keyword Não tokeniza — trata o campo inteiro como um único token
portuguese Analyzer com stemming e stopwords em português
english Analyzer com stemming e stopwords em inglês

Testando um analyzer

A API _analyze permite testar como um texto será processado por um analyzer, sem precisar indexar nada:

GET /_analyze
{
  "analyzer": "standard",
  "text": "Texto para análise!"
}

Testando apenas o tokenizer:

POST /_analyze
{
  "tokenizer": "standard",
  "text": "Quick brown fox."
}

Testando um analyzer definido inline — útil para testar sem precisar de um índice criado:

POST /_analyze
{
  "tokenizer": {
    "type": "edge_ngram",
    "min_gram": 3,
    "max_gram": 10,
    "token_chars": ["letter", "digit"]
  },
  "text": "GOL Linhas Aereas"
}

Para testar um analyzer customizado de um índice específico (como my_analyzer_ngram_3), use POST /nome-do-indice/_analyze — mas o índice precisa existir e ter o analyzer configurado. Esse exemplo prático está no Lab 6.5, onde o índice fornecedor é criado com esse analyzer.

Normalizers

Normalizers são semelhantes aos analyzers, mas aplicados a campos do tipo keyword. A diferença principal: um normalizer sempre produz exatamente um token por entrada — ele transforma o valor sem dividi-lo. São usados para normalizar valores antes de armazená-los, como converter para minúsculas.

PUT /meu_index
{
  "settings": {
    "analysis": {
      "normalizer": {
        "meu_normalizer": {
          "type": "custom",
          "char_filter": [],
          "filter": ["lowercase"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "meu_campo_keyword": {
        "type": "keyword",
        "normalizer": "meu_normalizer"
      }
    }
  }
}

Com esse normalizer, o valor "BOA TARDE" será armazenado e indexado como "boa tarde", tornando as buscas case-insensitive nesse campo.

POST /meu_index/_doc/
{
  "meu_campo_keyword": "BOA TARDE"
}
GET /meu_index/_search
{
  "size": 0,
  "aggs": {
    "meus_valores": {
      "terms": {
        "field": "meu_campo_keyword"
      }
    }
  }
}

6.3 - Aliases

Um alias é um nome alternativo que aponta para um ou mais índices. Para quem consome os dados (aplicações, dashboards, queries), o alias funciona exatamente como um índice — mas por trás pode estar apontando para um, vários índices ou até para um subconjunto filtrado de um índice.

Casos de uso comuns:

  • Abstração de versão: renomear ou reindexar dados sem alterar o nome que as aplicações usam
  • Alias multi-índice: fazer uma query em vários índices ao mesmo tempo por um único nome
  • Alias filtrado: expor apenas um subconjunto de documentos de um índice (ex: apenas registros de um cliente específico)
  • Write index: controlar em qual índice as escritas são direcionadas (usado pelo ILM)

Criando um alias simples

POST /_aliases
{
  "actions": [
    {
      "add": {
        "index": "clientes",
        "alias": "clientes_atuais"
      }
    }
  ]
}

A partir desse momento, clientes_atuais pode ser usado no lugar de clientes em qualquer operação de leitura.

Alias com filtro

POST /_aliases
{
  "actions": [
    {
      "add": {
        "index": "clientes",
        "alias": "clientes_adultos",
        "filter": {
          "range": {
            "idade": { "gte": 18 }
          }
        }
      }
    }
  ]
}

O alias clientes_adultos expõe apenas documentos de clientes com 18 anos ou mais. O filtro é aplicado automaticamente — quem usa o alias não precisa saber que ele existe.

Removendo um alias

POST /_aliases
{
  "actions": [
    {
      "remove": {
        "index": "clientes",
        "alias": "clientes_atuais"
      }
    }
  ]
}

Listando aliases

GET /_cat/aliases?v

6.4 - Laboratório 1: criando um índice com mapping explícito e dynamic templates

Neste laboratório, vamos criar um índice clientes com um mapping explícito para campos conhecidos e um dynamic template para tratar automaticamente campos de endereço como keyword.

Etapa 1 — Criar o índice com mapping

PUT /clientes
{
  "mappings": {
    "dynamic_templates": [
      {
        "logradouros_as_keywords": {
          "match_mapping_type": "string",
          "match_pattern": "regex",
          "match": "^logradouro.*",
          "mapping": {
            "type": "keyword"
          }
        }
      }
    ],
    "properties": {
      "codigo": {
        "type": "integer"
      },
      "nome": {
        "type": "text",
        "fields": {
          "keyword": { "type": "keyword" }
        }
      },
      "sexo":            { "type": "keyword" },
      "estado_civil":    { "type": "keyword" },
      "data_nascimento": { "type": "date" },
      "caracteristicas": { "type": "text" }
    }
  }
}

Explicação dos campos:

  • codigo: número inteiro
  • nome: texto livre com subcampo keyword para ordenação e agregações
  • sexo e estado_civil: valores exatos, sem análise de texto
  • data_nascimento: campo de data
  • caracteristicas: texto livre para full-text search
  • dynamic_templates: qualquer campo novo que comece com logradouro será automaticamente indexado como keyword

Etapa 2 — Indexar um documento de exemplo

POST /clientes/_doc/1
{
  "codigo": 123,
  "nome": "João Silva",
  "sexo": "masculino",
  "estado_civil": "casado",
  "data_nascimento": "1980-05-15",
  "caracteristicas": "Amigável, extrovertido, atencioso",
  "logradouro_principal": "Rua das Flores",
  "logradouro_secundario": "Avenida das Arvores"
}

Os campos logradouro_principal e logradouro_secundario não estão definidos no mapping — serão detectados pelo dynamic template e indexados como keyword automaticamente.

Etapa 3 — Validar o mapping aplicado

GET /clientes/_mapping

Confirme que logradouro_principal e logradouro_secundario aparecem com o tipo keyword no mapping retornado.

Etapa 4 — Testando os valores de dynamic

Testando dynamic: false — campos novos são armazenados mas não indexados:

PUT /clientes_strict
{
  "mappings": {
    "dynamic": "false",
    "properties": {
      "codigo": { "type": "integer" },
      "nome":   { "type": "text" }
    }
  }
}

Indexe um documento com um campo extra:

POST /clientes_strict/_doc/1
{
  "codigo": 1,
  "nome": "Teste",
  "campo_novo": "valor ignorado"
}

Tente buscar pelo campo_novo — nenhum resultado será retornado, pois o campo não foi indexado.

Testando dynamic: strict — documentos com campos não mapeados são rejeitados:

PUT /clientes_rigido
{
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "codigo": { "type": "integer" },
      "nome":   { "type": "text" }
    }
  }
}
POST /clientes_rigido/_doc/1
{
  "codigo": 1,
  "nome": "Teste",
  "campo_nao_mapeado": "isso vai falhar"
}

O Elasticsearch retornará um erro de mapping informando que campo_nao_mapeado não está definido no mapping do índice.


6.5 - Laboratório 2: customizando analyzers com edge_ngram

O edge_ngram é um tokenizer que gera tokens progressivos a partir do início de cada palavra. Por exemplo, o texto "GOL" com min_gram: 3 e max_gram: 5 gera os tokens GOL, GOLL, GOLLI (se o texto fosse mais longo). Isso é especialmente útil para implementar busca progressiva enquanto o usuário digita — semelhante ao autocomplete.

Passo 1 — Criar o índice com analyzer customizado

PUT /fornecedor
{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_analyzer_ngram_3": {
          "tokenizer": "split_3_ngram",
          "filter": ["lowercase"]
        }
      },
      "tokenizer": {
        "split_3_ngram": {
          "type": "edge_ngram",
          "min_gram": 3,
          "max_gram": 15,
          "token_chars": ["letter", "digit", "whitespace"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "codigo":          { "type": "integer" },
      "nome_fornecedor": {
        "type": "text",
        "fields": { "keyword": { "type": "keyword" } }
      },
      "nome_fornecedor_engram": {
        "type": "text",
        "analyzer": "my_analyzer_ngram_3",
        "search_analyzer": "standard",
        "fields": { "keyword": { "type": "keyword" } }
      },
      "cnpj":     { "type": "keyword" },
      "endereco": { "type": "keyword" },
      "bairro":   { "type": "keyword" },
      "cidade":   { "type": "keyword" },
      "uf":       { "type": "keyword" }
    }
  }
}

Nota importante sobre search_analyzer: no campo nome_fornecedor_engram, o analyzer de indexação é o my_analyzer_ngram_3 (que gera os tokens em ngram), mas o analyzer de busca é o standard. Isso é intencional — na indexação queremos gerar todos os tokens progressivos, mas na busca queremos tratar o termo digitado pelo usuário como um token inteiro, não tokenizá-lo em ngrams. Usar o mesmo analyzer de indexação na busca produziria resultados incorretos.

Passo 2 — Testar o tokenizer

Veja como o texto será dividido em tokens durante a indexação:

POST /fornecedor/_analyze
{
  "tokenizer": "split_3_ngram",
  "text": "GOLLINHASAEREAS"
}

Observe que serão gerados tokens progressivos: GOL, GOLL, GOLLI, GOLLL... até o max_gram configurado.

Passo 3 — Inserir documentos

POST /fornecedor/_doc/1
{
  "codigo": 123,
  "nome_fornecedor": "GOL Linhas Aereas",
  "nome_fornecedor_engram": "GOL Linhas Aereas",
  "cnpj": "12222334000101",
  "endereco": "Rua das Flores, 100",
  "bairro": "Centro",
  "cidade": "Caxias",
  "uf": "RJ"
}
POST /fornecedor/_doc/2
{
  "codigo": 124,
  "nome_fornecedor": "TAM Linhas Aereas",
  "nome_fornecedor_engram": "TAM Linhas Aereas",
  "cnpj": "12222334000102",
  "endereco": "Avenida Brasil, 200",
  "bairro": "Fulano",
  "cidade": "Santos",
  "uf": "SP"
}

Passo 4 — Realizar buscas com o campo ngram

GET /fornecedor/_search
{
  "query": {
    "match": {
      "nome_fornecedor_engram": "TAM"
    }
  }
}

Graças ao edge_ngram, mesmo digitando apenas TAM a busca encontrará TAM Linhas Aereas. Teste também com GOL e compare os resultados.


6.6 - Laboratório 3: criando aliases de índice

Neste laboratório, vamos criar dois índices representando a matriz e a filial de uma empresa, unificá-los com um alias e criar uma visão filtrada por estado.

Passo 1 — Criar os índices

PUT /fornecedor_matriz
{
  "mappings": {
    "properties": {
      "codigo":          { "type": "integer" },
      "nome_fornecedor": {
        "type": "text",
        "fields": { "keyword": { "type": "keyword" } }
      },
      "cnpj":     { "type": "keyword" },
      "endereco": { "type": "keyword" },
      "bairro":   { "type": "keyword" },
      "cidade":   { "type": "keyword" },
      "uf":       { "type": "keyword" }
    }
  }
}
PUT /fornecedor_filial
{
  "mappings": {
    "properties": {
      "codigo":          { "type": "integer" },
      "nome_fornecedor": {
        "type": "text",
        "fields": { "keyword": { "type": "keyword" } }
      },
      "cnpj":     { "type": "keyword" },
      "endereco": { "type": "keyword" },
      "bairro":   { "type": "keyword" },
      "cidade":   { "type": "keyword" },
      "uf":       { "type": "keyword" }
    }
  }
}

Passo 2 — Inserir documentos

POST /fornecedor_matriz/_doc/1
{
  "codigo": 124,
  "nome_fornecedor": "TAM Linhas Aereas",
  "cnpj": "12222334000102",
  "endereco": "Rua tal e etc",
  "bairro": "Fulano",
  "cidade": "Caxias",
  "uf": "RJ"
}
POST /fornecedor_filial/_doc/1
{
  "codigo": 124,
  "nome_fornecedor": "GOL Linhas Aereas",
  "cnpj": "12222334000102",
  "endereco": "Rua tal e etc",
  "bairro": "Fulano",
  "cidade": "Santos",
  "uf": "SP"
}

Passo 3 — Criar o alias corporacao

O alias corporacao aponta para os dois índices ao mesmo tempo. Uma busca pelo alias retorna dados de ambos:

POST /_aliases
{
  "actions": [
    { "add": { "index": "fornecedor_matriz", "alias": "corporacao" } },
    { "add": { "index": "fornecedor_filial", "alias": "corporacao" } }
  ]
}
GET /corporacao/_search

Passo 4 — Criar um alias filtrado fornecedores_sp

POST /_aliases
{
  "actions": [
    {
      "add": {
        "index": "fornecedor_*",
        "alias": "fornecedores_sp",
        "filter": {
          "term": { "uf": "SP" }
        }
      }
    }
  ]
}
GET /fornecedores_sp/_search

A busca retornará apenas documentos com uf: SP, independentemente de qual índice eles estão.


6.7 - Laboratório 4: aplicando todas as configurações de índice em conjunto

Neste laboratório vamos usar component templates e index templates para aplicar mapping, settings e uma política de ILM em múltiplos índices com uma única configuração. Esse é o padrão recomendado em produção para garantir consistência entre índices que seguem a mesma estrutura.

O fluxo é:

ILM Policy → Component Template → Index Template → Índices (criados automaticamente)

Passo 1 — Criar a ILM Policy

PUT /_ilm/policy/policy_pessoas
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {}
      },
      "warm": {
        "min_age": "1d",
        "actions": {
          "forcemerge": {
            "max_num_segments": 1
          }
        }
      },
      "delete": {
        "min_age": "30d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}

Nota sobre a action freeze e as fases cold e frozen: é importante não confundir as fases com as actions:

  • Action freeze: existia como action da fase cold e foi removida no Elasticsearch 9.x. Era usada para reduzir o uso de memória de índices pouco acessados.
  • Fase cold: continua existindo no 9.x e é totalmente válida. A partir do Elasticsearch 7.10, o ILM injeta automaticamente a action migrate nas fases warm e cold, atualizando o _tier_preference do índice para movê-lo ao tier correspondente — sem necessidade de configurar o allocate explicitamente. Opcionalmente, a action allocate pode ser usada para controlar o número de réplicas ou definir regras de alocação customizadas além do tier padrão.
  • Fase frozen: usa a action searchable_snapshot — os dados são movidos para um repositório de snapshots (S3, GCS, Azure) e ficam pesquisáveis sem ocupar disco local no cluster, mas com latência maior de acesso.

Este lab usa apenas hot, warm e delete para simplificar. A fase cold com migração automática de tier e a fase frozen com searchable_snapshot são abordadas junto com a arquitetura Hot-Warm-Cold-Frozen da Seção 4.

Passo 2 — Criar o component template

Um component template é um bloco reutilizável de configurações (settings, mappings, aliases) que pode ser incluído em um ou mais index templates. Isso evita repetição quando vários templates compartilham a mesma estrutura base.

PUT /_component_template/ct_pessoas
{
  "template": {
    "settings": {
      "number_of_shards": 1,
      "number_of_replicas": 1,
      "index.lifecycle.name": "policy_pessoas"
    },
    "mappings": {
      "properties": {
        "nome":  { "type": "text" },
        "idade": { "type": "integer" },
        "sexo":  { "type": "keyword" },
        "uf":    { "type": "keyword" }
      }
    },
    "aliases": {
      "pessoas": {}
    }
  }
}

Passo 3 — Criar o index template

O index template define o padrão de nome dos índices que receberão as configurações. O campo composed_of inclui o component template criado no passo anterior:

PUT /_index_template/it_pessoas
{
  "index_patterns": ["pessoas_*"],
  "composed_of": ["ct_pessoas"]
}

A partir desse momento, qualquer índice criado com o padrão pessoas_* receberá automaticamente o mapping, os settings e a ILM policy definidos no component template.

Passo 4 — Indexar documentos de exemplo

Como os índices pessoas_rj e pessoas_sp seguem o padrão pessoas_*, serão criados automaticamente com todas as configurações aplicadas:

POST /_bulk
{ "index": { "_index": "pessoas_rj", "_id": "1" } }
{ "nome": "João da Silva",   "sexo": "masculino", "idade": 19, "uf": "RJ" }
{ "index": { "_index": "pessoas_rj", "_id": "2" } }
{ "nome": "Maria Oliveira",  "sexo": "feminino",  "idade": 28, "uf": "RJ" }
{ "index": { "_index": "pessoas_rj", "_id": "3" } }
{ "nome": "Roberto Carlos",  "sexo": "masculino", "idade": 35, "uf": "RJ" }
{ "index": { "_index": "pessoas_rj", "_id": "4" } }
{ "nome": "Ana Maria",       "sexo": "feminino",  "idade": 14, "uf": "RJ" }
{ "index": { "_index": "pessoas_rj", "_id": "5" } }
{ "nome": "Paulo Souza",     "sexo": "masculino", "idade": 15, "uf": "RJ" }
POST /_bulk
{ "index": { "_index": "pessoas_sp", "_id": "1" } }
{ "nome": "Bruno Garcia",     "sexo": "masculino", "idade": 22, "uf": "SP" }
{ "index": { "_index": "pessoas_sp", "_id": "2" } }
{ "nome": "Renata Santos",    "sexo": "feminino",  "idade": 30, "uf": "SP" }
{ "index": { "_index": "pessoas_sp", "_id": "3" } }
{ "nome": "Gilberto Ferreira","sexo": "masculino", "idade": 48, "uf": "SP" }
{ "index": { "_index": "pessoas_sp", "_id": "4" } }
{ "nome": "Maria Silva",      "sexo": "feminino",  "idade": 12, "uf": "SP" }
{ "index": { "_index": "pessoas_sp", "_id": "5" } }
{ "nome": "Pedro Borges",     "sexo": "masculino", "idade": 15, "uf": "SP" }

Passo 5 — Verificar as configurações aplicadas

GET /pessoas_rj
GET /pessoas_sp
GET /pessoas/_search

Verifique que ambos os índices têm o mapping, os settings e a ILM policy aplicados conforme o component template, e que a busca pelo alias pessoas retorna documentos dos dois índices.

Clone this wiki locally