Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs Menu
Docs Home
/ /
/ / /

Relaciones integradas y referencias manuales

En esta guía, aprenderá a usar el proveedor MongoDB Entity Framework Core para modelar relaciones entre documentos en su base de datos MongoDB. El proveedor EF Core admite los siguientes tipos de relaciones:

  • Relaciones incrustadas: Subdocumentos incrustados directamente dentro de un documento padre. Este es el enfoque recomendado para las relaciones uno a uno y uno a muchos en MongoDB.

  • Referencias manuales: Un documento que hace referencia a otro almacenando su ID en un campo, en lugar de incrustarlo como un subdocumento. Este enfoque funciona bien para modelar relaciones de muchos a muchos o cuando se necesita acceder a los documentos de forma independiente.

Tip

Diseña tu esquema para patrones de consulta

Al modelar datos para MongoDB, primero determine las operaciones que su aplicación ejecuta con mayor frecuencia. Luego, elija una estructura de documentos que admita esas operaciones de manera eficiente. El esquema más eficiente en MongoDB podría no coincidir con el esquema que usaría para una base de datos relacional. En cambio, considere qué datos se recuperan comúnmente juntos, qué valores cambian con frecuencia y qué relaciones de datos cambian con el tiempo.

Para obtener más información sobre el modelado de datos y la migración de una base de datos relacional a MongoDB Server, consulte la Diagrama de mapeo de SQL a MongoDB y modelado de datos en MongoDB en la documentación del servidor MongoDB.

Para incrustar un subdocumento en un documento principal, especifique el modelo del documento incrustado como una entidad de propiedad. Las relaciones incrustadas son la forma nativa de MongoDB de modelar relaciones y ofrecen un mejor rendimiento para los documentos a los que se accede con frecuencia de forma conjunta.

Utilice documentos incrustados cuando los datos relacionados se visualizan habitualmente en el contexto de su documento principal y cuando el tamaño de los datos incrustados se mantiene razonablemente limitado. Esto incluye pequeños conjuntos de valores secundarios, como direcciones, configuraciones o una lista limitada de elementos recientes. Al incrustar documentos, MongoDB Server puede mejorar el rendimiento recuperando los datos relacionados en una sola operación de base de datos y actualizándolos de forma atómica dentro de un mismo documento.

Considere la posibilidad de incrustar datos en los siguientes casos:

  • Normalmente, tu aplicación lee los datos del elemento padre y del elemento hijo conjuntamente. Obtener toda la información en una sola consulta es más eficiente que realizar llamadas separadas.

  • Los datos relacionados no crecen sin un límite superior claro. Los datos limitados no harán que los documentos crezcan indefinidamente ni alcanzarán el límite de tamaño de documento de 16MB de MongoDB.

  • Los datos relacionados no cambian con frecuencia y son independientes del documento principal. Esto reduce la sobrecarga que supone reescribir el documento principal.

Nota

Jerarquías anidadas

Al actualizar cualquier propiedad de una entidad anidada, el proveedor de EF Core reescribe todo el documento raíz. En jerarquías de entidades con tres o más niveles de anidamiento, este coste de escritura se agrava, ya que un pequeño cambio en las profundidades del árbol desencadena la reescritura completa del documento padre. Si su modelo utiliza un anidamiento profundo y su aplicación realiza escrituras frecuentes, considere aplanar la jerarquía o reemplazar las entidades internas con referencias manuales.

Para obtener más información, consulte Datos incrustados en la documentación del servidor MongoDB.

Puede designar una entidad de su propiedad de las siguientes maneras:

  • [Propiedad] Atributo: Aplicar el [Owned] Atributo de anotación de datos a la clase del modelo para el subdocumento. Este enfoque es declarativo y conciso, pero también menos flexible, ya que se aplica globalmente a todos los usos del tipo en cuestión.

  • API fluida: Llama a OwnsOne() los OwnsMany() métodos o en tu DbContext configuración. Este enfoque ofrece mayor control y flexibilidad, permitiéndote configurar la relación de forma diferente para entidades específicas sin modificar la clase del modelo.

Las siguientes secciones ofrecen ejemplos de estos enfoques para modelar entidades de propiedad única y múltiple.

Para incrustar un único documento dentro de un documento padre, llame al método OwnsOne() en su configuración DbContext o aplique el atributo [Owned] a la clase incrustada.

El siguiente ejemplo muestra una entidad Customer que contiene un documento Address incrustado. Seleccione el [Owned] Attribute o Fluent API pestaña para ver la sintaxis correspondiente:

[Owned]
public class Address
{
public string Street { get; set; } = null!;
public string City { get; set; } = null!;
public string Country { get; set; } = null!;
}
public class Customer
{
public ObjectId Id { get; set; }
public string Name { get; set; } = null!;
public Address Address { get; set; } = null!;
}
public class CustomerDbContext : DbContext
{
public DbSet<Customer> Customers { get; set; } = null!;
public CustomerDbContext(DbContextOptions options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Customer>(c =>
{
c.OwnsOne(c => c.Address);
c.ToCollection("customers");
});
}
}

Cuando guardas una entidad Customer, MongoDB almacena la Address como un documento incrustado dentro del documento Customer. El siguiente JSON muestra cómo aparece esta relación en MongoDB:

{
"_id": ObjectId("..."),
"Name": "John Doe",
"Address": {
"Street": "123 Main St",
"City": "New York",
"Country": "USA"
}
}

Para incrustar varios documentos en un documento principal, llame al método OwnsMany() o aplique el atributo [Owned] a la clase incrustada y defina una propiedad de colección.

El siguiente ejemplo muestra una entidad Customer que contiene varios documentos Order incrustados. Seleccione la pestaña [Owned] Attribute o Fluent API para ver la sintaxis correspondiente:

[Owned]
public class Order
{
public string Product { get; set; } = null!;
public int Quantity { get; set; }
}
public class CustomerWithOrders
{
public ObjectId Id { get; set; }
public string Name { get; set; } = null!;
public List<Order> Orders { get; set; } = new();
}
public class OrderDbContext : DbContext
{
public DbSet<CustomerWithOrders> Customers { get; set; } = null!;
public OrderDbContext(DbContextOptions options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<CustomerWithOrders>(c =>
{
c.OwnsMany(c => c.Orders);
c.ToCollection("customers");
});
}
}

Cuando guardas una entidad CustomerWithOrders, MongoDB almacena la Orders como una matriz de documentos incrustados, como se muestra en el siguiente JSON:

{
"_id": ObjectId("..."),
"Name": "Jane Smith",
"Orders": [
{ "Product": "Laptop", "Quantity": 1 },
{ "Product": "Mouse", "Quantity": 2 }
]
}

Para modelar las relaciones entre entidades que no están incrustadas, puede almacenar las referencias manualmente guardando el ID de un documento en un campo de otro documento. Este método requiere que gestione la relación en el código de su aplicación.

Utilice referencias cuando consulte regularmente los datos relacionados independientemente de su elemento principal, cuando el conjunto de datos secundarios pueda llegar a ser muy grande o cuando los datos relacionados cambien con frecuencia.

Considere utilizar referencias en los siguientes casos:

  • Los datos relacionados crecen sin un límite superior definido. Los arreglos sin límite pueden causar problemas de rendimiento y podrían alcanzar el límite de tamaño de documento de 16MB de MongoDB.

  • Debes consultar la entidad relacionada por separado. Puedes consultar e indexar la colección secundaria directamente sin necesidad de escanear los documentos principales.

  • Los datos relacionados cambian con frecuencia y de forma independiente del documento principal. Las actualizaciones frecuentes de los datos incrustados requieren reescribir todo el documento principal cada vez, lo cual resulta ineficiente.

  • La aplicación no suele leer los datos del elemento padre y del elemento hijo conjuntamente. Al usar referencias, se evita obtener datos del elemento hijo que no se necesitan.

  • La relación es de muchos a muchos o compleja de alguna otra manera.

  • Duplicar los datos generaría una sobrecarga de actualización excesiva.

Para obtener más información,consulte los datos de referencia en la documentación del servidor MongoDB.

El siguiente ejemplo muestra cómo almacenar una referencia a una entidad relacionada:

public class Author
{
public ObjectId Id { get; set; }
public string Name { get; set; } = null!;
}
public class Book
{
public ObjectId Id { get; set; }
public string Title { get; set; } = null!;
// Store reference to Author by storing the Author's Id
public ObjectId AuthorId { get; set; }
}

Para recuperar la entidad relacionada, debe consultar la colección referenciada por separado, como se muestra en el siguiente ejemplo:

// Query a book and its author
var book = db.Books.FirstOrDefault(b => b.Title == "My Book");
var author = db.Authors.FirstOrDefault(a => a.Id == book!.AuthorId);

Si un documento principal contiene una matriz grande, pero su aplicación suele utilizar solo los elementos más recientes o a los que se accede con mayor frecuencia, considere el patrón de subconjunto.

En el patrón de subconjuntos, se conservan los elementos a los que se accede con mayor frecuencia en el documento principal y el resto se traslada a una colección separada. Este enfoque puede reducir el tamaño del documento y mantener una mayor parte del conjunto de trabajo en la memoria RAM, lo que puede mejorar el rendimiento de las consultas.

Este patrón resulta útil cuando se desean las ventajas de rendimiento de la incrustación, pero un historial incrustado completo provocaría que los documentos fueran demasiado grandes o demasiado costosos de cargar.

Para obtener más información sobre las mejores prácticas para el diseño de esquemas en MongoDB, consulte las secciones "Mejores prácticas para el modelado de datos en MongoDB" y "Diseño de su esquema" en la documentación del servidor MongoDB.

Para obtener más información sobre el modelado de datos en MongoDB, consulte la sección "Modelado de datos" en la documentación del servidor MongoDB.

Para obtener más información sobre los tipos de entidades propias en Entity Framework Core, consulte Tipos de entidades propias en la documentación de Microsoft Entity Framework Core.

Para obtener más información sobre los métodos y tipos que se describen en esta guía, consulte la siguiente documentación de la API de Microsoft:

Volver

Escritura de datos

En esta página