Engenharia

Adeus, types. Olá, typeless.

Desde a versão 5.0, estamos abrindo caminho para remover os types do Elasticsearch e, com a versão 7.0, eles caíram em desuso. O objetivo dos types era oferecer a possibilidade de ser multi-tenancy dentro de um único índice, o que é incompatível com o Lucene. Infelizmente, os types acabaram causando mais problema do que qualquer outra coisa. Depois de longas discussões sobre o que fazer (usar campos únicos por type ou ter um índice por type), decidimos remover o recurso. Para facilitar a transição para os usuários, diluímos as alterações em 4 grandes versões:

  • Na 5.0, campos que têm o mesmo nome em diversos types têm mapeamentos compatíveis.
  • Na 6.0, começamos a impedir novos índices de ter mais do que um type e colocamos em desuso o mapeamento _default_.
  • Na 7.0, deixamos de usar APIs que aceitam types, introduzimos novas APIs typeless e acabamos com o suporte para o mapeamento _default_.
  • A versão 8.0 vai remover APIs que aceitam types.

APIs typeless

Todas as APIs que aceitam types no caminho do URL, corpo da solicitação ou da resposta estão recebendo uma contraparte typeless. É o caso de algumas APIs muito comuns, como criação de índice, índice e GET. Um exemplo vale mais do que mil palavras, então veja como é uma interação com um cluster 7.0 com APIs typeless.

PUT index
{
  "mappings": {
    "properties": { // Note how there is no top-level key with the type name
      "@timestamp": {
        "type": "date"
      }
    }
  }
}
PUT index/_doc/1 // _doc becomes the new endpoint for document index, get and delete requests
{
  "@timestamp": "2019-02-20"
}
POST index/_bulk
{"index": {"_id": "2"}} // no _type in the URL or in document metadata
{"@timestamp": "2019-03-01"}
{"update": {"_id": "1"}}
{"@timestamp": "2019-02-21"}
GET index/_doc/2
GET index/_search // unchanged, the `GET index/{type}/_search` endpoint is deprecated however
{
  "query": {
    "range": {
      "@timestamp": {
        "gte": "2019-01-01"
      }
    }
  }
}
GET index/_explain/1 // note how the type does not appear in the URL anymore, this would have been "GET index/{type}/1/_explain" in 6.x
{
  "query": {
    "range": {
      "@timestamp": {
        "gte": "2019-01-01"
      }
    }
  }
}

O que preciso fazer?

Algumas mudanças já estão acontecendo e vão precisar que você faça alterações em seu cluster antes de atualizar para a versão 7.0. Outras só serão necessárias no upgrade para a versão 8.0 e devem ser feitas depois da atualização para a 7.0.

Antes do upgrade

Veja se você está na versão 6.8

Se você pretende fazer o upgrade sem tempo de inatividade, primeiro faça para a 6.8, que é a única versão 6.x a ter recursos como suporte ao parâmetro include_type_name, necessário para um upgrade sem problemas para a 7.0.

Pare de usar mapeamentos _default_

O mapeamento _default_ vai acabar na 7.0. Se algum índice da 6.x tiver mapeamento _default_, ele vai funcionar sem problemas, já que o mapeamento _default_ só será rejeitado nos novos índices.

Você precisa atualizar seus modelos de índice e seu código do aplicativo para adicionar esses mapeamentos ao type atual em vez de incluí-los no mapeamento _default_. Se o nome do type não for importante para você, recomendamos usar _doc, pois isso facilitará a transição para as APIs typeless no futuro.

Passe include_type_name=true para as APIs de criação de índice, modelo e mapeamento.

A mudança para APIs typeless significa que as APIs cujo corpo da solicitação tenha exigido um type hoje terão um formato diferente:

  • create index
  • put mapping
  • put template

enquanto outras APIs que retornavam types como resposta terão outro formato de resposta:

  • get index
  • get mapping
  • get field mapping
  • get template

Para não se prejudicar com essa mudança, você deve fazer seu aplicativo passar include_type_name=true para essas chamadas API, que é um no-op na 6.x e dirá para a 7.x fazer essas APIs se comportarem como faziam na 6.x. Por exemplo, veja uma chamada de criação de índice com esse parâmetro. Funciona do mesmo jeito na 6.8 e na 7.x.

PUT index?include_type_name=true
{
  "mappings": {
    "my_type": {
      "properties": { // Note how there is no top-level key with the type name
        "@timestamp": {
          "type": "date"
        }
      }
    }
  }
}

Depois do upgrade

Se você seguiu as etapas de pré-upgrade recomendadas, tudo deve continuar funcionando. No entanto, nesse momento, você ainda está usando APIs que aceitam types e isso gera alertas de desuso. Para evitar isso, é importante passar para as APIs typeless.

Para APIs de modelo e mapeamentos e criação de índice, você precisará remover include_type_name=true dos parâmetros do URL e alterar os corpos da solicitação ou expectativas sobre o formato de resposta, que não incluem mais types. Normalmente, se o corpo da solicitação ou a resposta incluíssem mapeamentos, eles teriam uma seção assim:

{
  "my_type": { // this key is no longer accepted in mappings as of 7.0
    "properties": ...
  }
}
{
  "properties": ...
}

Para outras APIs, como de índice, GET ou de atualização, você precisa substituir o nome do type na URL por _doc. Isso funcionará independentemente do nome do type no seu índice. Por exemplo, se você realizava chamadas de índice para um índice cujo nome de type fosse my_type, a chamada do índice era assim:

PUT index/my_type/1
{
  "@timestamp": "2019-02-20"
}
PUT index/_doc/1
{
  "@timestamp": "2019-02-20"
}

Saiba mais

Se quiser saber mais sobre a remoção de types e como migrar para APIs typeless, recomendo dar uma olhada na documentação sobre remoção de types, em que falamos em mais detalhes sobre as implicações dessa mudança e como se preparar para ela.

Baixe a versão 7.0.0, experimente as APIs typeless e conte para nós o que achou em uma discussão.