paint-brush
Modelado de datos en Elasticsearch: uso de consultas anidadas y relaciones entre padres e hijospor@rocksetcloud
7,992 lecturas
7,992 lecturas

Modelado de datos en Elasticsearch: uso de consultas anidadas y relaciones entre padres e hijos

por Rockset10m2024/04/17
Read on Terminal Reader

Demasiado Largo; Para Leer

Administrar relaciones en Elasticsearch puede ser un desafío, pero tenemos consultas anidadas y relaciones entre padres e hijos para solucionarlo, y más.
featured image - Modelado de datos en Elasticsearch: uso de consultas anidadas y relaciones entre padres e hijos
Rockset HackerNoon profile picture
0-item
1-item



El modelado de datos en Elasticsearch no es tan obvio como cuando se trata de bases de datos relacionales. A diferencia de las bases de datos relacionales tradicionales que dependen de la normalización de datos y uniones SQL, Elasticsearch requiere enfoques alternativos para gestionar las relaciones.


Existen cuatro soluciones alternativas comunes para gestionar relaciones en Elasticsearch:


  • Uniones del lado de la aplicación

  • Desnormalización de datos

  • Tipos de campos anidados y consultas anidadas

  • Relaciones entre padres e hijos


En este blog, analizaremos cómo puede diseñar su modelo de datos para manejar relaciones utilizando el tipo de campo anidado y las relaciones padre-hijo. Cubriremos la arquitectura, las implicaciones de rendimiento y los casos de uso de estas dos técnicas.

Tipos de campos anidados y consultas anidadas

Elasticsearch admite estructuras anidadas, donde los objetos pueden contener otros objetos. Los tipos de campos anidados son objetos JSON dentro del documento principal, que pueden tener sus propios campos y tipos distintos. Estos objetos anidados se tratan como documentos ocultos separados a los que solo se puede acceder mediante una consulta anidada.


Los tipos de campos anidados son adecuados para relaciones en las que la integridad de los datos, el estrecho acoplamiento y la estructura jerárquica son importantes. Estas incluyen relaciones uno a uno y uno a muchos donde hay una entidad principal. Por ejemplo, representar a una persona y sus múltiples direcciones y números de teléfono en un solo documento.


Con los tipos de campos anidados, Elasticsearch almacena el documento completo, así como los objetos principales y anidados, en un único bloque y segmento de Lucene. Esto puede dar como resultado velocidades de consulta más rápidas ya que la relación está contenida en un documento.


Ejemplo de tipo de campo anidado y consulta anidada

Veamos un ejemplo de una publicación de blog con comentarios. Queremos anidar los comentarios debajo de la publicación del blog para que puedan consultarse juntos fácilmente en el mismo documento.


GITHUB JULIE-MILLS

 { "post_id": "1", "title": "Introduction to Elasticsearch Data Modeling", "content": "Exploring various data modeling options in Elasticsearch.", "comments": [ { "comment_id": "101", "text": "Great overview of data modeling!" }, { "comment_id": "102", "text": "Looking forward to more content." } ] }


Beneficios de los tipos de campos anidados y las consultas anidadas

Los beneficios de las relaciones de objetos anidados incluyen:


  • Los datos se almacenan en el mismo bloque y segmento de Lucene: almacenar objetos anidados en el mismo bloque y segmento de Lucene genera consultas más rápidas porque los datos están ubicados.
  • Integridad de los datos: debido a que las relaciones se mantienen dentro del mismo documento, se puede garantizar la precisión en las consultas anidadas.
  • Modelo de datos de documentos: fácil para desarrolladores familiarizados con el modelo de datos NoSQL en el que se consultan documentos y datos anidados dentro de ellos.

Inconvenientes de los tipos de campos anidados y las consultas anidadas

  • Ineficiencia de la actualización : las actualizaciones, inserciones y eliminaciones de cualquier parte de un documento con objetos anidados requieren volver a indexar todo el documento, lo que puede consumir mucha memoria, especialmente si los documentos son grandes o las actualizaciones son frecuentes.


  • Rendimiento de consultas con campos anidados grandes : si tiene documentos con campos anidados particularmente grandes, esto puede tener implicaciones en el rendimiento. Esto se debe a que la solicitud de búsqueda recupera el documento completo.


  • Múltiples niveles de anidamiento pueden volverse complejos : ejecutar consultas en estructuras anidadas con múltiples niveles aún puede volverse complejo. Esto se debe a que las consultas pueden involucrar consultas anidadas dentro de consultas anidadas, lo que genera código menos legible.

Relaciones entre padres e hijos

En el mapeo padre-hijo, los documentos se organizan en tipos padre e hijo. Cada documento secundario tiene una asociación directa con un documento principal. Esta relación se establece a través de un valor de campo específico en el documento secundario que coincide con el ID del padre. El modelo padre-hijo adopta un enfoque descentralizado donde los documentos padre-hijo existen de forma independiente.


Las uniones entre padres e hijos son adecuadas para relaciones de uno a muchos o de muchos a muchos entre entidades. Imagine una aplicación en la que desea crear relaciones entre empresas y contactos y desea buscar empresas y contactos, así como contactos de empresas específicas.


Elasticsearch hace que las uniones entre padres e hijos sean eficientes al realizar un seguimiento de qué padres están conectados y qué hijos y al hacer que ambas entidades residan en el mismo fragmento. Al localizar la operación de unión, Elasticsearch evita la necesidad de una comunicación extensa entre fragmentos, lo que puede ser un cuello de botella en el rendimiento.

Ejemplo de relaciones entre padres e hijos

Tomemos el ejemplo de una relación entre padres e hijos para publicaciones y comentarios de blogs. Cada entrada del blog, es decir, la de los padres, puede tener varios comentarios, es decir, los hijos. Para crear la relación padre-hijo, indexemos los datos de la siguiente manera:


 PUT my-index-000001 { "mappings": { "properties": { "post_id": { "type": "keyword" }, "post_id": { "type": "join", "relations": { "post": "comment" } } } } }


Un documento principal sería una publicación similar a esta:


 { "post_id": "1", "title": "Introduction to Elasticsearch Data Modeling", "content": "Exploring various data modeling options in Elasticsearch." }


El documento secundario sería entonces un comentario que contiene el post_id que lo vincula con su documento principal.


 { "comment_id": "101", "text": "Great overview of data modeling!", "post_id": "1" }


Beneficios de las relaciones entre padres e hijos

Los beneficios del modelado entre padres e hijos incluyen:


  • Se asemeja al modelo de datos relacionales : en las relaciones padre-hijo, los documentos padre e hijo están separados y están vinculados por una identificación principal única. Esta configuración se acerca más a un modelo de base de datos relacional y puede resultar más intuitiva para quienes estén familiarizados con dichos conceptos.


  • Eficiencia de actualización : los documentos secundarios se pueden agregar, modificar o eliminar sin afectar el documento principal u otros documentos secundarios. Esto es particularmente beneficioso cuando se trata de una gran cantidad de documentos secundarios que requieren actualizaciones frecuentes. Tenga en cuenta que asociar un documento secundario con un padre diferente es un proceso más complejo ya que el nuevo padre puede estar en otro fragmento.


  • Más adecuado para niños heterogéneos : dado que los documentos secundarios se almacenan por separado, pueden ser más eficientes en cuanto a memoria y almacenamiento, especialmente en los casos en los que hay muchos documentos secundarios con diferencias de tamaño significativas.

Inconvenientes de las relaciones entre padres e hijos

Los inconvenientes de las relaciones entre padres e hijos incluyen:


  • Consultas costosas y lentas : unir documentos a través de índices separados agrega trabajo computacional durante la ejecución de la consulta, lo que nuevamente afecta el rendimiento. Elasticsearch señala que las consultas entre padres e hijos pueden ser entre 5 y 10 veces más lentas que las consultas de objetos anidados.


  • Gastos generales de mapeo : las relaciones entre padres e hijos pueden consumir más memoria y recursos de caché. Elasticsearch mantiene un mapa de relaciones entre padres e hijos, que puede crecer y consumir una cantidad significativa de memoria, especialmente con un gran volumen de documentos.


  • Gestión del tamaño de los fragmentos : dado que tanto los documentos principales como los secundarios residen en el mismo fragmento, existe un riesgo potencial de distribución desigual de los datos en todo el clúster. Algunos fragmentos pueden llegar a ser significativamente más grandes que otros, especialmente si hay documentos principales con muchos hijos. Esto puede generar desafíos en la gestión y ampliación del clúster de Elasticsearch .


  • Reindexación y mantenimiento del clúster : si necesita reindexar datos o cambiar la estrategia de fragmentación , la relación padre-hijo puede complicar este proceso. Deberá asegurarse de que se mantenga la integridad de la relación durante dichas operaciones. Las tareas rutinarias de mantenimiento del clúster, como el reequilibrio de fragmentos o las actualizaciones de nodos, pueden volverse más complejas. Se debe tener especial cuidado para garantizar que las relaciones entre padres e hijos no se interrumpan durante estos procesos.


Elastic , la compañía detrás de Elasticsearch, siempre recomendará que realice uniones del lado de la aplicación, desnormalización de datos y/u objetos anidados antes de seguir el camino de las relaciones padre-hijo.

Comparación de funciones de consultas anidadas y relaciones entre padres e hijos

La siguiente tabla proporciona un resumen de las características de los tipos de campos anidados y las consultas y las relaciones entre padres e hijos para comparar los enfoques de modelado de datos uno al lado del otro.



Tipos de campos anidados y consultas anidadas

Relaciones entre padres e hijos

Definición

Anida un objeto dentro de otro objeto

Vincula documentos principales y secundarios

Relaciones

Uno a uno, uno a muchos

Uno a muchos, muchos a muchos

Velocidad de consulta

Generalmente más rápido que las relaciones padre-hijo ya que los datos se almacenan en el mismo bloque y segmento.

Generalmente es entre 5 y 10 veces más lento que los objetos anidados, ya que los documentos principal y secundario se unen en el momento de la consulta.

Flexibilidad de consulta

Menos flexible que las consultas entre padres e hijos, ya que limita el alcance de la consulta dentro de los límites de cada objeto anidado.

Ofrece más flexibilidad en las consultas, ya que los documentos principales o secundarios se pueden consultar juntos o por separado.

Actualizaciones de datos

La actualización de objetos anidados requirió la reindexación de todo el documento

Actualizar documentos secundarios es más fácil ya que no es necesario volver a indexar todos los documentos.

Gestión

Gestión más sencilla ya que todo está contenido en un único documento

Más complejo de administrar debido a la indexación separada y al mantenimiento de relaciones entre los documentos principales y secundarios.

Casos de uso

Almacene y consulte datos complejos con múltiples niveles de jerarquía

Relaciones en las que hay pocos padres y muchos hijos, como productos y reseñas de productos.


Alternativas a Elasticsearch para modelado de relaciones

Si bien Elasticsearch proporciona varias soluciones para las uniones de estilo SQL , incluidas consultas anidadas y relaciones entre padres e hijos, está establecido que estos modelos no se escalan bien. Al diseñar aplicaciones a escala, puede tener sentido considerar un enfoque alternativo con capacidades de unión SQL nativas, Rockset .


Rockset es una base de datos de búsqueda y análisis diseñada para búsquedas SQL, agregaciones y uniones de cualquier dato, incluidos datos JSON profundamente anidados. A medida que los datos se transmiten a Rockset, se codifican en las estructuras de datos centrales de la base de datos que se utilizan para almacenar e indexar los datos para una recuperación rápida. Rockset indexa los datos de una manera que permite consultas rápidas, incluidas uniones, utilizando su optimizador de consultas basado en SQL. Como resultado, no se requiere un modelado de datos inicial para admitir uniones SQL.


Uno de los desafíos de Elasticsearch es cómo preservar la relación de manera eficiente cuando se actualizan los datos. Una de las razones es que Elasticsearch se basa en Apache Lucene, que almacena datos en segmentos inmutables, lo que hace que sea necesario volver a indexar todos los documentos. Rockset utiliza RocksDB, un almacén clave-valor de código abierto de Meta y creado para mutaciones de datos, para poder admitir de manera eficiente actualizaciones a nivel de campo sin necesidad de volver a indexar documentos completos.

Comparación de Elasticsearch y Rockset usando un ejemplo del mundo real

Comparemos el enfoque de relación padre-hijo en Elasticsearch con una consulta SQL en Rockset.


En el ejemplo anterior de relación entre padres e hijos, modelamos publicaciones con múltiples comentarios creando dos tipos de documentos:


  • publicaciones o el tipo de documento principal

  • comentarios o los tipos de documentos secundarios


Usamos un identificador único, el ID del padre, para establecer la relación entre los documentos padre e hijo. En el momento de la consulta, utilizamos Elasticsearch DSL para recuperar comentarios de una publicación específica.


En Rockset, los datos que contienen publicaciones se almacenarían en una colección, una tabla en el mundo relacional, mientras que los datos que contienen comentarios se almacenarían en una colección separada. En el momento de la consulta, uniríamos los datos mediante una consulta SQL.


Aquí están los dos enfoques uno al lado del otro:


Relaciones entre padres e hijos en Elasticsearch


 POST /blog/posts/1 { "title": "Elasticsearch Modeling", "content": "A post about data modeling in Elasticsearch" } POST /blog/comments/2?parent=1 { "text": "Great post!" } POST /blog/comments/3?parent=1 { "text": "I learned a lot from this." }


Para recuperar una publicación por su título y todos sus comentarios, deberá crear una consulta de la siguiente manera.


 GET /posts/_search { "query": { "bool": { "must": [ { "match": { "title": "Exploring Elasticsearch Models" } } ] } }, "inner_hits": { "_source": ["text"], "name": "comments", "path": "comments" } }


SQL en Rockset

Para luego consultar estos datos, sólo necesita escribir una consulta SQL simple.


 SELECT p.title, p.content, c.text FROM posts p JOIN comments c ON p.post_id = c.post_id WHERE p.post_id = 1;


Si tiene varios conjuntos de datos que deben unirse para su aplicación, Rockset es más sencillo y escalable que Elasticsearch. También simplifica las operaciones, ya que no necesita remodelar sus datos, administrar actualizaciones ni reindexar operaciones.

Gestión de relaciones en Elasticsearch

Este blog proporcionó una descripción general de los tipos de campos anidados, las consultas anidadas y las relaciones entre padres e hijos en Elasticsearch con el objetivo de ayudarlo a determinar el mejor enfoque de modelado de datos para su carga de trabajo.


Los tipos de campos anidados y las consultas son útiles para relaciones uno a uno o uno a muchos donde la relación se mantiene dentro de un solo documento. Este se considera un enfoque más simple y escalable para la gestión de relaciones.


El modelo de relación padre-hijo es más adecuado para relaciones de uno a muchos o de muchos a muchos, pero presenta una mayor complejidad, especialmente porque las relaciones deben estar contenidas en un fragmento específico.


Si uno de los requisitos principales de su aplicación es modelar relaciones, puede tener sentido considerar Rockset. Rockset simplifica el modelado de datos y ofrece un enfoque más escalable para la gestión de relaciones mediante uniones SQL. Puede comparar y contrastar el rendimiento de Elasticsearch y Rockset iniciando una prueba gratuita con $300 en créditos hoy.