sql >> Base de Datos >  >> NoSQL >> MongoDB

MongoDB - Crear una relación

Para crear una relación en MongoDB, incruste un documento BSON dentro de otro o haga referencia a él desde otro.

Las bases de datos MongoDB funcionan de manera diferente a las bases de datos relacionales. Esto también se aplica a las relaciones.

En MongoDB, puede crear una relación utilizando uno de los dos métodos siguientes:

  • Documentos incrustados.
  • Documentos de referencia.

El método que utilice dependerá de los datos y de cómo pretenda consultar esos datos.

Relaciones integradas

Con MongoDB, puede incrustar documentos dentro de documentos. Por lo tanto, un solo documento puede contener sus propias relaciones.

De hecho, ya creamos una relación usando este método cuando creamos un documento por primera vez.

Relación uno a uno

Una relación de uno a uno es donde el documento principal tiene un elemento secundario y el elemento secundario tiene un elemento principal.

Por ejemplo, una regla comercial podría decir que un artista solo puede tener una dirección y que la dirección solo puede pertenecer a un artista.

El siguiente código crea una relación uno a uno, incrustada dentro del documento.

db.artists.insert(
    {
        _id : 2,
        artistname : "Prince",
        address :   {
                        street : "Audubon Road",
                        city : "Chanhassen",
                        state : "Minnesota",
                        country : "United States"
                    }
    }
)

Resultado:

WriteResult({ "nInserted" : 1 })

Relación de uno a muchos

Un uno a muchos relación es donde el documento principal puede tener muchos documentos secundarios, pero los documentos secundarios solo pueden tener un documento principal.

Entonces, otra regla comercial podría decir que un artista puede tener muchos álbumes, pero un álbum solo puede pertenecer a un artista.

Ejecutar el siguiente código creará una relación de uno a muchos:

db.artists.insert(
    {
        _id : 3,
        artistname : "Moby",
        albums : [
                    {
                        album : "Play",
                        year : 1999,
                        genre : "Electronica"
                    }, 
                    {
                        album : "Long Ambients 1: Calm. Sleep.",
                        year : 2016,
                        genre : "Ambient"
                    }
                ]
    }
)

Resultado:

WriteResult({ "nInserted" : 1 })

Relaciones de referencia de documentos

Puede utilizar una referencia de documento para crear una relación. En lugar de incrustar el documento secundario en el documento principal (como hicimos anteriormente), separa el documento secundario en su propio documento independiente.

Así que podríamos hacer esto:

Documento principal

db.artists.insert(
    {
        _id : 4,
        artistname : "Rush"
    }
)

Documentos del niño

Insertaremos 3 documentos secundarios, uno para cada miembro de la banda:

db.musicians.insert(
    {
        _id : 9,
        name : "Geddy Lee",
        instrument : [ "Bass", "Vocals", "Keyboards" ],
        artist_id : 4
    }
)
db.musicians.insert(
    {
        _id : 10,
        name : "Alex Lifeson",
        instrument : [ "Guitar", "Backing Vocals" ],
        artist_id : 4
    }
)
db.musicians.insert(
    {
        _id : 11,
        name : "Neil Peart",
        instrument : "Drums",
        artist_id : 4
    }
)

Consultar la relación

Después de insertar los dos documentos anteriores, puede usar $lookup para realizar una combinación externa izquierda en las dos colecciones.

Esto, junto con aggregate() método y $match para especificar el artista específico que le interesa, devolverá los documentos principales y secundarios en uno.

db.artists.aggregate([
    {
      $lookup:
        {
          from: "musicians",
          localField: "_id",
          foreignField: "artist_id",
          as: "band_members"
        }
   },
   { $match : { artistname : "Rush" } }
]).pretty()

Resultado:

{
	"_id" : 4,
	"artistname" : "Rush",
	"band_members" : [
		{
			"_id" : 9,
			"name" : "Geddy Lee",
			"instrument" : [
				"Bass",
				"Vocals",
				"Keyboards"
			],
			"artist_id" : 4
		},
		{
			"_id" : 10,
			"name" : "Alex Lifeson",
			"instrument" : [
				"Guitar",
				"Backing Vocals"
			],
			"artist_id" : 4
		},
		{
			"_id" : 11,
			"name" : "Neil Peart",
			"instrument" : "Drums",
			"artist_id" : 4
		}
	]
}

Puedes ver que los primeros dos campos son de la colección de artistas, y el resto es de la colección de músicos.

Entonces, si solo consulta la colección de artistas por sí misma:

db.artists.find( { artistname : "Rush" } )

Solo obtendrías esto:

{ "_id" : 4, "artistname" : "Rush" }

No se devuelven datos relacionados.

Cuándo usar documentos incrustados frente a documentos de referencia

Ambos métodos de crear relaciones tienen sus pros y sus contras. Hay ocasiones en las que puede usar documentos incrustados y otras veces usará documentos de referencia.

Cuándo usar relaciones incrustadas

Uno de los principales beneficios de utilizar el método de relación integrada es el rendimiento. Cuando la relación está incrustada en el documento, las consultas se ejecutarán más rápido que si estuvieran distribuidas en varios documentos. MongoDB solo necesita devolver un documento, en lugar de unir varios documentos para recuperar las relaciones. Esto puede proporcionar un gran aumento del rendimiento, especialmente cuando se trabaja con muchos datos.

Las relaciones incrustadas también facilitan la redacción de consultas. En lugar de escribir consultas complejas que unen muchos documentos a través de su identificador único, puede devolver todos los datos relacionados en una sola consulta.

Otra consideración a tener en cuenta es que MongoDB solo puede garantizar la atomicidad a nivel de documento. Las actualizaciones de documentos para un solo documento siempre son atómicas, pero no para múltiples documentos.

Cuando varios usuarios acceden a los datos, siempre existe la posibilidad de que dos o más usuarios intenten actualizar el mismo documento con datos diferentes. En este caso, MongoDB se asegurará de que no ocurra ningún conflicto y solo se actualice un conjunto de datos a la vez. MongoDB no puede garantizar esto en varios documentos.

Por lo tanto, en general, las relaciones incrustadas se pueden usar en la mayoría de los casos, siempre que el documento se mantenga dentro del límite de tamaño (16 megabytes en el momento de la escritura) y/o su límite de anidamiento (100 niveles de profundidad en el momento de la escritura).

Sin embargo, las relaciones incrustadas no son apropiadas para todos ocasiones. Puede haber situaciones en las que tenga más sentido crear una relación de referencia de documento.

Cuándo usar relaciones referenciadas

Para los datos que deben repetirse en muchos documentos, puede ser útil tenerlos en su propio documento separado. Esto puede reducir los errores y ayudar a mantener la coherencia de los datos (teniendo en cuenta que las actualizaciones de varios documentos no son atómicas).

Usando el ejemplo anterior, un músico podría ser miembro (o ex-miembro) de muchas bandas. Algunos también pueden producir álbumes para otros artistas, enseñar a estudiantes, realizar clínicas, etc. Además, se podría almacenar una gran cantidad de datos contra cada músico. Así que tener un documento separado para cada músico tiene sentido en este caso.

Además, si cree que sus documentos incrustados pueden exceder el límite de tamaño de archivo impuesto por MongoDB, deberá almacenar algunos datos en documentos separados.