Posso fazer junções no estilo SQL no Elasticsearch?


Elasticsearch é um mecanismo de pesquisa e análise distribuído de código aberto baseado em JSON, criado usando Apache Lucene com o objetivo de fornecer funcionalidade de pesquisa rápida em tempo actual. É um armazenamento de dados NoSQL orientado a documentos, escalonável e sem esquema por padrão. O Elasticsearch foi projetado para funcionar em escala com grandes conjuntos de dados. Como mecanismo de pesquisa, ele fornece indexação rápida e recursos de pesquisa que podem ser dimensionados horizontalmente em vários nós.

Plugue sem vergonha: Conjunto de foguetes é um banco de dados de indexação em tempo actual na nuvem. Ele cria automaticamente índices otimizados não apenas para pesquisa, mas também para agregações e junções, tornando mais rápido e fácil para seus aplicativos consultar dados, independentemente de onde eles vêm e em que formato estão. Mas esta postagem é para destacar algumas soluções alternativas , caso você realmente queira fazer junções no estilo SQL no Elasticsearch.

Por que os relacionamentos de dados são importantes?

Vivemos em um mundo altamente conectado, onde o gerenciamento de relacionamentos de dados é importante. Os bancos de dados relacionais são bons para lidar com relacionamentos, mas com requisitos de negócios em constante mudança, o esquema fixo desses bancos de dados resulta em problemas de escalabilidade e desempenho. O uso de armazenamentos de dados NoSQL está se tornando cada vez mais widespread devido à sua capacidade de enfrentar uma série de desafios associados às abordagens tradicionais de manipulação de dados.

As empresas lidam continuamente com estruturas de dados complexas onde agregações, junções e recursos de filtragem são necessários para analisar os dados. Com a explosão de dados não estruturados, há um número crescente de casos de uso que exigem a união de dados de diferentes fontes para fins de análise de dados.

Embora as junções sejam principalmente um Conceito SQLeles também são igualmente importantes no mundo NoSQL. As junções no estilo SQL não são suportadas no Elasticsearch como cidadãos de primeira classe. Este artigo discutirá como definir relacionamentos no Elasticsearch usando várias técnicas, como desnormalização, junções do lado do aplicativo, documentos aninhados e relacionamentos pai-filho. Também explorará os casos de uso e os desafios associados a cada abordagem.

Como lidar com relacionamentos no Elasticsearch

Como o Elasticsearch não é um banco de dados relacional, junta-se não existem como funcionalidade nativa como em um banco de dados SQL. Ele se concentra mais na eficiência da pesquisa do que na eficiência do armazenamento. Os dados armazenados são praticamente nivelados ou desnormalizados para impulsionar casos de uso de pesquisa rápida.

Existem várias maneiras de definir relacionamentos no Elasticsearch. Com base no seu caso de uso, você pode selecionar uma das técnicas abaixo no Elasticsearch para modelar seus dados:

  • Relacionamentos um para um: mapeamento de objetos
  • Relacionamentos um-para-muitos: documentos aninhados e o modelo pai-filho
  • Relacionamentos muitos-para-muitos: desnormalização e junções do lado do aplicativo

Os mapeamentos de objetos um-para-um são simples e não serão muito discutidos aqui. O restante deste weblog cobrirá os outros dois cenários com mais detalhes.


Quer saber mais sobre junções no Elasticsearch? Confira nossa postagem sobre casos de uso comuns


Gerenciando seu modelo de dados no Elasticsearch

Existem quatro abordagens comuns para gerenciar dados no Elasticsearch:

  1. Desnormalização
  2. Junções do lado do aplicativo
  3. Objetos aninhados
  4. Relacionamentos pai-filho

Desnormalização

A desnormalização fornece o melhor desempenho de pesquisa de consulta no Elasticsearch, já que não é necessário unir conjuntos de dados no momento da consulta. Cada documento é independente e contém todos os dados necessários, eliminando assim a necessidade de dispendiosas operações de junção.

Com a desnormalização, os dados são armazenados em uma estrutura achatada no momento da indexação. Embora isso aumente o tamanho do documento e resulte no armazenamento de dados duplicados em cada documento. O espaço em disco não é um bem caro e, portanto, pouco motivo de preocupação.

Casos de uso para desnormalização

Ao trabalhar com sistemas distribuídos, ter que unir conjuntos de dados na rede pode introduzir latências significativas. Você pode evitar essas caras operações de junção desnormalizando os dados. Relacionamentos muitos-para-muitos podem ser tratados por nivelamento de dados.

Desafios com a desnormalização de dados

  • A duplicação de dados em documentos nivelados requer espaço de armazenamento adicional.
  • O gerenciamento de dados em uma estrutura nivelada incorre em sobrecarga adicional para conjuntos de dados de natureza relacional.
  • Do ponto de vista da programação, a desnormalização requer sobrecarga adicional de engenharia. Você precisará escrever código adicional para nivelar os dados armazenados em várias tabelas relacionais e mapeá-los para um único objeto no Elasticsearch.
  • Desnormalizar dados não é uma boa ideia se seus dados mudam com frequência. Nesses casos, a desnormalização exigiria a atualização de todos os documentos quando qualquer subconjunto de dados fosse alterado e, portanto, deveria ser evitada.
  • A operação de indexação leva mais tempo com conjuntos de dados nivelados, pois mais dados estão sendo indexados. Se os seus dados forem alterados com frequência, isso indicará que a sua taxa de indexação é mais alta, o que pode causar problemas de desempenho do cluster.

Junções do lado do aplicativo

As junções do lado do aplicativo podem ser usadas quando há necessidade de manter o relacionamento entre documentos. Os dados são armazenados em índices separados e as operações de junção podem ser executadas no lado do aplicativo durante o tempo de consulta. No entanto, isso implica a execução de consultas adicionais no momento da pesquisa em seu aplicativo para unir documentos.

Casos de uso para junções do lado do aplicativo

As junções do lado do aplicativo garantem que os dados permaneçam normalizados. As modificações são feitas em um só lugar e não há necessidade de atualizar constantemente seus documentos. A redundância de dados é minimizada com esta abordagem. Este método funciona bem quando há menos documentos e as alterações de dados são menos frequentes.

Desafios com junções do lado do aplicativo

  • O aplicativo precisa executar diversas consultas para unir documentos no momento da pesquisa. Se o conjunto de dados tiver muitos consumidores, será necessário executar o mesmo conjunto de consultas diversas vezes, o que pode levar a problemas de desempenho. Essa abordagem, portanto, não aproveita o poder actual do Elasticsearch.
  • Esta abordagem resulta em complexidade ao nível da implementação. Requer escrever código adicional no nível do aplicativo para implementar operações de junção para estabelecer um relacionamento entre documentos.

Objetos aninhados

A abordagem aninhada pode ser usada se você precisar manter o relacionamento de cada objeto na matriz. Os documentos aninhados são armazenados internamente como documentos Lucene separados e podem ser unidos no momento da consulta. São junções de tempo de índice, onde vários documentos Lucene são armazenados em um único bloco. Da perspectiva do aplicativo, o bloco se parece com um único documento do Elasticsearch. A consulta é, portanto, relativamente mais rápida, uma vez que todos os dados residem no mesmo objeto. Documentos aninhados lidam com relacionamentos um-para-muitos.

Casos de uso para documentos aninhados

A criação de documentos aninhados é preferencial quando seus documentos contêm matrizes de objetos. A Figura 1 abaixo mostra como o tipo aninhado no Elasticsearch permite que matrizes de objetos sejam indexadas internamente como documentos Lucene separados. Lucene não tem conceito de objetos internos, por isso é interessante ver como o Elasticsearch transforma internamente o documento unique em campos nivelados com vários valores.

Uma vantagem de usar consultas aninhadas é que ele não fará correspondências entre objetos, portanto, resultados de correspondência inesperados são evitados. Ele está ciente dos limites dos objetos, tornando as pesquisas mais precisas.


Posso fazer junções no estilo SQL no Elasticsearch?

Figura 1: Matrizes de objetos indexados internamente como documentos Lucene separados no Elasticsearch usando abordagem aninhada

Desafios com objetos aninhados

  • O objeto raiz e seus objetos aninhados devem ser completamente reindexados para adicionar/atualizar/excluir um objeto aninhado. Em outras palavras, uma atualização de registro filho resultará na reindexação de todo o documento.
  • Documentos aninhados não podem ser acessados ​​diretamente. Eles só podem ser acessados ​​pelo documento raiz relacionado.
  • As solicitações de pesquisa retornam o documento inteiro em vez de retornar apenas os documentos aninhados que correspondem à consulta de pesquisa.
  • Se o seu conjunto de dados for alterado com frequência, o uso de documentos aninhados resultará em um grande número de atualizações.

Relacionamentos Pai-Filho

As relações entre pais e filhos potencializam juntar tipo de dados para separar completamente objetos com relacionamentos em documentos individuais – pai e filho. Isso permite armazenar documentos em uma estrutura relacional em documentos separados do Elasticsearch que podem ser atualizados separadamente.

As relações entre pais e filhos são benéficas quando os documentos precisam ser atualizados com frequência. Esta abordagem é, portanto, excellent para cenários em que os dados mudam frequentemente. Basicamente, você separa o documento base em vários documentos contendo pai e filho. Isso permite que os documentos pai e filho sejam indexados/atualizados/excluídos independentemente um do outro.

Pesquisando em documentos pai e filho

Para otimizar o desempenho do Elasticsearch durante a indexação e pesquisa, a recomendação geral é garantir que o tamanho do documento não seja grande. Você pode aproveitar o modelo pai-filho para dividir seu documento em documentos separados.

No entanto, existem alguns desafios na implementação disso. Os documentos pai e filho precisam ser roteados para o mesmo fragmento para que a união deles durante o tempo de consulta seja feita na memória e de forma eficiente. O ID pai precisa ser usado como valor de roteamento para o documento filho. O _parent O campo fornece ao Elasticsearch o ID e o tipo do documento pai, o que permite internamente rotear os documentos filhos para o mesmo fragmento do documento pai.

Elasticsearch permite pesquisar em objetos JSON complexos. Isso, no entanto, requer um entendimento completo da estrutura de dados para consultá-los com eficiência. O modelo pai-filho aproveita vários filtros para simplificar a funcionalidade de pesquisa:

Retorna documentos pais que possuem documentos filhos correspondentes à consulta.

Aceita um pai e retorna documentos filho aos quais os pais associados corresponderam.

Busca informações relevantes sobre crianças do has_child consulta.

A Figura 2 mostra como você pode usar o modelo pai-filho para demonstrar relacionamentos um-para-muitos. Os documentos filho podem ser adicionados/removidos/atualizados sem afetar o pai. O mesmo vale para o documento pai, que pode ser atualizado sem reindexar os filhos.


elasticsearch-pai-filho

Figura 2: Modelo pai-filho para relacionamentos um-para-muitos

Desafios com relacionamentos entre pais e filhos

  • As consultas são mais caras e consomem muita memória devido à operação de junção.
  • Há uma sobrecarga nas construções pai-filho, pois são documentos separados que devem ser unidos no momento da consulta.
  • Precisa garantir que o pai e todos os seus filhos existam no mesmo fragmento.
  • Armazenar documentos com relacionamentos pai-filho envolve complexidade de implementação.

Conclusão

Escolhendo o Elasticsearch certo modelagem de dados o design é elementary para o desempenho e a manutenção do aplicativo. Ao projetar seu modelo de dados no Elasticsearch, é importante observar os vários prós e contras de cada um dos quatro métodos de modelagem discutidos aqui.

Neste artigo, exploramos como objetos aninhados e relacionamentos pai-filho permitem operações de junção semelhantes a SQL no Elasticsearch. Você também pode implementar lógica personalizada em seu aplicativo para lidar com relacionamentos com junções do lado do aplicativo. Para casos de uso em que você precisa unir vários conjuntos de dados no Elasticsearch, você pode ingerir e carregar esses dois conjuntos de dados no índice do Elasticsearch para permitir consultas de alto desempenho.

Pronto para uso, o Elasticsearch não possui junções como em um banco de dados SQL. Embora existam possíveis soluções alternativas para estabelecer relacionamentos em seus documentos, é importante estar ciente dos desafios que cada uma dessas abordagens apresenta.


Blog do CTA Sequoia Capital

Usando junções SQL nativas com Rockset

Quando há necessidade de combinar vários conjuntos de dados para análise em tempo actual, um banco de dados que fornece junções SQL nativas pode lidar melhor com esse caso de uso. Assim como o Elasticsearch, o Rockset é usado como uma camada de indexação em dados de bancos de dados, fluxos de eventos e information lakes, permitindo a ingestão sem esquema dessas fontes. Ao contrário do Elasticsearch, o Rockset oferece a capacidade de consulta com SQL completoincluindo junções, proporcionando maior flexibilidade na forma como você pode usar seus dados.



Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *