kb.erickguedes.com
Elasticsearch: Busca e Analytics

Fundamentos e Mapeamento

Aula 1 de 6

Instalação e Primeiros Passos

O Elasticsearch é um motor de busca e analytics distribuído, baseado em Apache Lucene.

Instalação via Docker

docker network create elastic
docker pull docker.elastic.co/elasticsearch/elasticsearch:8.14.0

docker run -d --name es-node --net elastic \
  -p 9200:9200 -p 9300:9300 \
  -e "discovery.type=single-node" \
  -e "xpack.security.enabled=false" \
  -e "ES_JAVA_OPTS=-Xms1g -Xmx1g" \
  docker.elastic.co/elasticsearch/elasticsearch:8.14.0

# Verificar health
curl http://localhost:9200/_cluster/health

Instalação no Ubuntu/Debian

wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
echo "deb https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
sudo apt update && sudo apt install elasticsearch
sudo systemctl start elasticsearch

Elastic Cloud

# Via API do Elastic Cloud
curl -u "username:password" \
  -X POST "https://api.elastic-cloud.com/api/v1/deployments" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "meu-cluster",
    "version": "8.14.0",
    "region": "us-east-1"
  }'

Gerenciamento de Índices

# Criar índice
PUT /produtos
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1
  }
}

# Listar todos os índices
GET /_cat/indices?v

# Obter configuração de um índice
GET /produtos/_settings

# Deletar índice
DELETE /produtos

Mapeamento (Mapping)

O mapping define o schema — tipos dos campos, analisadores e comportamento de indexação.

Mapeamento Explícito

PUT /produtos
{
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "nome": {
        "type": "text",
        "analyzer": "standard",
        "fields": {
          "keyword": { "type": "keyword" }
        }
      },
      "descricao": { "type": "text", "analyzer": "brazilian" },
      "preco": { "type": "float" },
      "categoria": { "type": "keyword" },
      "tags": { "type": "keyword" },
      "data_criacao": { "type": "date", "format": "yyyy-MM-dd" },
      "ativo": { "type": "boolean" },
      "estoque": { "type": "integer" },
      "localizacao": { "type": "geo_point" }
    }
  }
}

Tipos de Campo

TipoDescriçãoUso
textTexto analisado (tokenizado)Busca full-text
keywordValor exato, não analisadoFiltros, sorting, aggregations
integer / longNúmeros inteirosContagem, range
float / doubleNúmeros decimaisPreços, métricas
booleanVerdadeiro/falsoFlags
dateData/horaTimestamps
ipEndereço IPLogs de rede
geo_pointCoordenadas latitude/longitudeMapas, geolocalização
nestedObjetos aninhados indexados separadamenteArrays de objetos
flattenedObjeto indexado como um campo únicoDados semi-estruturados
joinRelacionamento parent/childHierarquias

Normalizer em Keyword

PUT /categorias
{
  "mappings": {
    "properties": {
      "nome": {
        "type": "keyword",
        "normalizer": "lowercase_normalizer"
      }
    }
  },
  "settings": {
    "analysis": {
      "normalizer": {
        "lowercase_normalizer": {
          "type": "custom",
          "filter": ["lowercase", "asciifolding"]
        }
      }
    }
  }
}

CRUD de Documentos

# Indexar (criar/substituir)
PUT /produtos/_doc/1
{
  "nome": "Notebook Dell XPS",
  "preco": 8999.90,
  "categoria": "eletronicos",
  "data_criacao": "2025-01-15"
}

# Obter documento
GET /produtos/_doc/1

# Atualizar parcialmente
POST /produtos/_update/1
{
  "doc": {
    "preco": 8499.90
  }
}

# Deletar
DELETE /produtos/_doc/1

# Bulk API
POST /_bulk
{"index": {"_index": "produtos", "_id": "2"}}
{"nome": "Mouse Logitech", "preco": 249.90, "categoria": "perifericos"}
{"index": {"_index": "produtos", "_id": "3"}}
{"nome": "Teclado Mecânico", "preco": 599.90, "categoria": "perifericos"}

Lab: E-commerce Index

# 1. Crie um índice "produtos" com mapping explícito
#    - nome (text + keyword), preco (float), categoria (keyword)
#    - tags (keyword), data_criacao (date), descricao (text com analyzer brazilian)
# 2. Indexe 5 documentos via Bulk API
# 3. Atualize o preço de um produto
# 4. Busque por um termo com _search
# 5. Delete um documento e verifique
curl -X DELETE "http://localhost:9200/produtos"

O mapeamento correto é a base de um cluster performático. Escolher entre text e keyword, definir analisadores e evitar dynamic mapping são decisões críticas.