ES|QL Joins chegaram! Sim, Joins!
O Elasticsearch 8.18 inclui o comando LOOKUP JOIN do ES|QL, nosso primeiro JOIN no estilo SQL.

O Elasticsearch 8.18 inclui nosso primeiro JOIN no estilo SQL: o comando LOOKUP JOIN do ES|QL. Agora está disponível em prévia técnica e possibilita correlação e enriquecimento de dados com conjuntos de dados de consulta facilmente atualizáveis. Precisa adicionar informações de host e ativos aos seus eventos? Sem problema. Quer verificar quais endereços IP ou URLs estão nas listas de inteligência de ameaças? Claro! Fazer atualizações no conjunto de dados de consulta e usá-las imediatamente? Vamos nessa!
Lookup Join é um LEFT OUTER JOIN no estilo SQL que depende de um novo modo de índice chamado lookup para o lado direito. O índice de lookup pode incluir ativos, dados de inteligência sobre ameaças como IPs conhecidos como ruins, informações de pedidos, informações de funcionários ou clientes — há possibilidades infinitas.

Historicamente, o Elasticsearch não possuía capacidade de junção (join), embora ao longo do tempo algumas tentativas tenham sido feitas nessa direção, como os tipos de campo "nested", "_parent" e "join", além do recurso de enriquecimento (enrich). Costumávamos incentivar a desnormalização dos dados colocando os dados de referência junto com os eventos no mesmo índice, ou realizando junções no lado do cliente. Essas solutions prejudicam a escalabilidade para grandes volumes de dados e podem ser limitantes quando há uma grande variedade de dados e casos de uso. Chegou a hora de o Elasticsearch contar com junções. E agora isso é possível: ES|QL não é apenas uma linguagem — é construída sobre um novo mecanismo de computação. O mecanismo ES|QL possibilita a execução de recursos avançados como junções.
Para ativar os Lookup Joins, criamos um novo modo de índice: lookup. Um índice lookup é basicamente como um índice normal (mode:standard é o padrão), o que significa que é diretamente atualizável. A principal diferença é que um índice lookup é apenas um shard. Assim, é limitado a 2 bilhões de documentos, um limite do Lucene para um shard. Isso deve ser mais do que suficiente para armazenar os dados do “lado direito” de alguns dos muitos casos de uso de junção lookup. A imposição desse limite nos ajuda a evitar alguns dos problemas associados a uniões totalmente distribuídas, reduzindo a cardinalidade de origem do lado direito da junção. Isso também nos diz quais conjuntos de dados você planeja usar como referências lookup para que possamos encontrar maneiras de otimizá-los no futuro.
Além do modo de índice de consulta, não há restrições sobre os dados de origem nem qualquer preparação de dados necessária para realizar uma junção. Isso significa que é fácil adicionar conjuntos de dados de consulta e mantê-los atualizados.
Parte disso já foi possível com o comando ENRICH em ES|QL. O ENRICH foi otimizado para consultas de tempo de ingestão em pipelines de ingestão e para conjuntos de dados pequenos que não mudam com frequência, sendo, portanto, conveniente, mas não ideal. Lookup Join é mais fácil de configurar e gerenciar do que ENRICH:
Não há políticas de enriquecimento a serem criadas
Sem execução de políticas
Índices de consulta são graváveis
Há menos cópias dos dados
Melhor manejo de múltiplas correspondências — enquanto o enrich cria campos multivalorados quando há múltiplas correspondências, a join de busca cria múltiplas linhas. Isso facilita a realização de analíticas adicionais, como agrupamento e agregação, como bytes transferidos por usuário ou totais de pedidos.
O Lookup Join permite especificação em tempo real do campo de correspondência
Aqui estão apenas algumas das maneiras de usar um LOOKUP JOIN:
Participar de eventos de segurança com inteligência de ameaças para enriquecer ainda mais o evento
Consultar meu conjunto atual de hosts em relação à última inteligência de ameaças ou metadados internos
Correlacionar leituras de IOT com metadados estáticos ou dinâmicos (fabricante, unidade de volume)
Combinar eventos de segurança com informações do host para obter mais contexto e facilitar a filtragem
Adicionar alguns fatos como criticidade de ativos (este usuário é um executivo)
Adicionar os AIDs do CrowdStrike a uma fonte que tenha nomes de host
Verificar se certos endereços IP estão nos feeds de inteligência de ameaças
Adicionar informações de funcionários aos eventos
As possibilidades são infinitas.
Exemplo de uso
Vamos olhar alguns exemplos reais para ver como isso pode ser fácil e poderoso.
Como SRE, talvez seja necessário:
Adicionar um ambiente aos logs com base no endereço IP ou nome do host
Associar informações de funcionários a registros
Descobrir qual equipe é responsável por um servidor
Antes do LOOKUP JOIN, você teria que:
Colocar seus dados de referência (ambientes) em um índice
Definir uma política de enriquecimento com base nesse índice, especificando o tipo de política, o campo de correspondência e os campos de enriquecimento
Executar a política de enriquecimento uma vez para construir o índice de enriquecimento
Repetir para cada conjunto de dados de referência (funcionários, equipes)
Executar a política de enriquecimento sempre que os dados mudarem
Com o LOOKUP JOIN, basta inserir os dados de referência em um índice LOOKUP e pronto!
Imagine que você recebeu um alerta de que há usuários recebendo erros no seu site de comércio eletrônico. Você encontra logs da web onde a resposta não é o código HTTP 200 para sucesso. Você gostaria de separar esses dados por ambiente para ver se os clientes de produção são afetados, mas os registros não têm campo de ambiente. Tudo bem — basta adicionar uma junção de busca no ambiente, talvez usando um arquivo como este:
clientip,environment
192.168.1.9,QA
192.168.14.2,Dev
192.168.12.3,Prod
…Agora, adicione o LOOKUP JOIN no índice de pesquisa de ambientes (o meu se chama envs_lkp):
FROM kibana_sample_data_logs | WHERE response.keyword != "200"
| LOOKUP JOIN envs_lkp ON clientip
| STATS COUNT(*) by response, environment
Existem erros em Produção e Garantia de Qualidade (QA). Podemos fazer uma junção com uma lista de qual equipe é responsável por cada servidor web para ver com quem devemos entrar em contato:
host,team
www.elastic.co,Web team
artifacts.elastic.co,Delivery team
cdn.elastic-elastic-elastic.org,Cloud team
elastic-elastic-elastic.org,Web teamFROM kibana_sample_data_logs | WHERE response.keyword != "200"
| LOOKUP JOIN teams_lkp ON host
| STATS num = COUNT(*) by host, response.keyword, team
| SORT num DESC
Os analistas de segurança amam seus joins! Talvez eles queiram:
Identificar os IPs de clientes que estão solicitando URLs maliciosas conhecidas
Correlacionar com informações de ativos para agrupar eventos e atribuir prioridade ou risco
Você pode baixar uma lista de URLs maliciosas do URLhaus no Abuse.ch e carregá-la para um índice de busca.
FROM logs
| LOOKUP JOIN urlhaus_lkp ON url
| WHERE threat IS NOT NULL
| KEEP @timestamp, url.keyword, clientip, threat
Como criar pesquisas
Você vai precisar de pelo menos um índice lookup para usar o lookup join. Estamos criando formas de facilitar a criação e atualização de lookups no Kibana. Por enquanto, você pode começar criando um índice lookup de algumas maneiras — o detalhe principal é que o modo índice deve ser “lookup”.
Criar Índice de Pesquisa usando o Gerenciamento de Índices
No painel de navegação à esquerda do Kibana, clique em Stack Management e, em seguida, Gerenciamento de Índice. No lado direito, clique em Criar índice.

Forneça um nome de índice e selecione "Pesquisa" no menu suspenso do modo índice:

Clique em Criar para criar um índice de pesquisa vazio.
Criar índice de pesquisa via APIs
Crie um índice de pesquisa usando a API de criação de índice — certifique-se de incluir o modo do índice:
PUT mylookupindex
{
"settings": {
"index.mode": "lookup"
}
}Criar índice de busca usando o carregador de arquivos ML
No painel de navegação à esquerda do Kibana, clique em Machine learning e, em seguida, File Data Visualizer (ou digite "carregar" na barra de busca do Kibana).

Selecione ou arraste e solte seu arquivo — o CSV funciona bem para isso.
Depois de clicar em Importar, forneça um nome para o índice e clique em Avançado para revelar as configurações do índice. Aqui, adicione o index.mode: lookup.

Complete o carregamento do arquivo clicando em Importar. Um índice e um Data view serão criados.
Em todos os casos, agora você pode consultar o índice de pesquisa no seu ES|QL.
Respondendo a perguntas comuns
Q: Quando não devo usar joins?
O Lookup Join é realmente poderoso, mas com grande poder... bem, você sabe. Joins podem ser operações caras, e cada join adiciona alguma latência à sua pesquisa. Ainda podem existir cenários em que uma join seja um exagero ou não seja a melhor opção. Por exemplo, se houver um campo que você frequentemente usa em muitas pesquisas, considere desnormalizá-lo no índice esquerdo. Adicione-o no momento da ingestão usando um processador de enriquecimento na ingestão, configuração do agente de envio de arquivos, use um Logstash filter, etc. Esse processamento único na ingestão é um compromisso entre um leve aumento no uso de armazenamento e consultas mais rápidas. Isso seria mais aplicável para valores de referência que não mudam com frequência (o nome do usuário de um ID de usuário) ou que nunca mudam (o fabricante de um host).
Q: Posso pesquisar um lookup diretamente?
Sim! Um índice lookup é basicamente "apenas um índice", então você pode consultá-lo com o ES|QL.
FROM <lookup_index> | …Ou crie um data view.

P: Posso enviar dados do Logstash ou do agente?
Sim! Só tenha em mente que um índice de pesquisa não é um fluxo de dados e é apenas um shard, então você pode enviar "apenas" até 2 bilhões de documentos para cada índice de consulta.
O que vem a seguir?
Estamos trabalhando para remover algumas limitações conhecidas para que as joins de pesquisa estejam disponíveis para todos. Além disso, estamos projetando uma experiência de edição de primeira classe para os conjuntos de dados de pesquisa. Imagine poder criar e editar índices de busca diretamente no Kibana Discover, ou colocar um arquivo CSV no Discover para preencher o índice. Aqui está um protótipo de como isso pode ficar:

E as joins de pesquisa são só o começo. Gostaríamos de oferecer outros tipos úteis de joins, como junções INNER ou subconsultas, e também permitir junção contra qualquer índice (não apenas índices de pesquisa).
Começar
Essa é a função join de pesquisa, disponível no Elasticsearch 8.18/9.0 como prévia técnica.
Tudo pronto para começar? Elastic 8.18 e 9.0 estão agora disponíveis no Elastic Cloud — o Elasticsearch Service hospedado que inclui todos os novos recursos desta versão mais recente. Em nome da equipe do ES|QL, estamos ansiosos pelo seu feedback — você pode usar o botão "Enviar feedback" no editor do ES|QL no Discover. E olha só, conseguimos escrever este post sobre joins sem fazer nenhum trocadilho com junções... obrigado por acompanhar!
O lançamento e o tempo de amadurecimento de todos os recursos ou funcionalidades descritos neste artigo permanecem a exclusivo critério da Elastic. Os recursos ou funcionalidades não disponíveis no momento poderão não ser entregues ou não chegarem no prazo previsto.