No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Relaciones 1 a muchos referenciadas

16/22
Recursos

Aportes 9

Preguntas 0

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

pipeline => Permite omitir campos del otro documento que no quiero traer, es de buen uso cuando por ejemplo quiero traer una order y usuario, pero por seguridad no retornar el password del usuario.

db.inventory2.aggregate([
    {
        $match: ObjectId('12e21j321321') 
    },
    {
        $lookup: {
            pipeline: [
                {$project: {identification_number: 0, password: 0, createdAt: 0, updatedAt: 0, token: 0}},
            ],
            from :'inventory1',
            localField: 'iduser',
            foreignField: 'iduser',
            as: 'detail'
        }
    },
    {
        $unwind: '$detail'
    }
])

Relaciones 1 a Muchos referenciadas

En las relaciones 1 a muchos referenciadas un documento puede estar asociado a otros documentos de otra coleccion, esto mediante una identificacion que normalmente estan en la otra coleccion y que indican al documento.

<h5>Casos de uso</h5>
  • Cuando la relacion puede incrementar considerablemente
  • Cuando la entidad se actualiza de forma constante
  • Cuando la entidad es usada por muchos documentos
<h5>Ejemplo</h5>

Se tiene que un usuario puede tener varias ordenes. Entonces mediante relacionarlos con una identificacion de usuario en las ordenes de compra se puede saber a que usuario pertenecen.

// Crear un usuario
db.users.insertOne({
    name: 'pedro',
    address: 'San carlos 123'
})

// Conseguir el object id del usuario
db.users.findOne({name: 'pedro'}) 
/* Resultado
{
  "_id": {
    "$oid": "6497b8b4affb4e4355c4f297"
  },
  "name": "pedro",
  "address": "San carlos 123"
}
*/

// Con el object id del usuario (_id.$oid) se le agrega a las ordenes

db.orders.insertMany([
    {
        user_id: ObjectId('6497b8b4affb4e4355c4f297'),
        total: 1300,
        date: '2023-23-25'
    },
    {
        user_id: ObjectId('6497b8b4affb4e4355c4f297'),
        total: 2400,
        date: '2023-12-02'
    },
])

// Para buscar las ordenes asociadas al usuario
db.orders.find({
    user_id: ObjectId('6497b8b4affb4e4355c4f297')
})

// para un usuario, mostrarme sus ordenes
// Lookup del agregation framework
db.users.aggregate([
    {
        $lookup: { // join
          from: `orders`,
          localField: `_id`,
          foreignField: 'user_id',
          as: 'orders'
        }
    }
])

/* Resultado
[
  {
    "_id": {
      "$oid": "6497b8b4affb4e4355c4f297"
    },
    "name": "pedro",
    "address": "San carlos 123",
    "orders": [
      {
        "_id": {
          "$oid": "6497b99410c8b687cb183d29"
        },
        "user_id": {
          "$oid": "6497b8b4affb4e4355c4f297"
        },
        "total": 1300,
        "date": "2023-23-25"
      },
      {
        "_id": {
          "$oid": "6497b99410c8b687cb183d2a"
        },
        "user_id": {
          "$oid": "6497b8b4affb4e4355c4f297"
        },
        "total": 2400,
        "date": "2023-12-02"
      }
    ]
  }
]
*/

// Consultar por una sola orden de compra
db.orders.aggregate([
    {
        $match: { // filtrar
          _id: ObjectId('6497b99410c8b687cb183d2a') // order id
        }
    },
    {
        $lookup: { //Join
          from: `users`,
          localField: `user_id`,
          foreignField: '_id',
          as: 'user'
        }
    }
])

/* Resultado
[
  {
    "_id": {
      "$oid": "6497b99410c8b687cb183d2a"
    },
    "user_id": {
      "$oid": "6497b8b4affb4e4355c4f297"
    },
    "total": 2400,
    "date": "2023-12-02",
    "user": [
      {
        "_id": {
          "$oid": "6497b8b4affb4e4355c4f297"
        },
        "name": "pedro",
        "address": "San carlos 123"
      }
    ]
  }
]
*/

Solucion al reto 😄
en $match: el id del user que quiero consultar

db.users.aggregate([
    {
        $match: {
          _id: ObjectId('63c1656be362e371c8e95a45')
        }
    },
    {
        $lookup: {
          from: 'orders', 
          localField: '_id', 
          foreignField: 'user_id', 
          as: 'order'
        }
    }
])

Es importante no abusar del uso del $lookup, sobre todo cuando tienen muchos (miles o millones) de documentos y se quieren sacar datos de varias otras collecciones. Ahi la performance de aggregate se reduce bastante.

Si Zule es la esposa, es muy tierno

El código del reto:

use('store')
db.users.aggregate([
    {
        $match: {
            "_id": ObjectId("6458eb75303a528fbd1cb44b")
        }
    },
    {
        $lookup: {
            from: "orders",
            localField: "_id",
            foreignField: "userId",
            as: "orders"
        }
    },
    {
        $project: {
            "_id": 0,
            "name": 1,
            "orders.date": 1,
            "orders.orderId": 1,
            "orders.items.quantity": 1,
            "orders.items.price": 1
        }
    },
])

Me gusta tu curso, pero hubiese sido más facil de explicar poniendo un caso con un ID fijo en lugar del ObjectID, sinceramente me he perdido.

Muestra las ordenes de cada usuario segun el id dado en el $match

Usando projection en ambas colecciones

use("platzi_store")

// muestra todas las ordenes de un usuario
//omitiendo la 'password', y el 'user_id' de referencia de cada orden
db.users.aggregate([
  {
    $match: {
      _id: ObjectId('63dc480941d8383c5926809e')
    }
  },
  {    
    /**
     * from: The target collection.
     * localField: The local join field.
     * foreignField: The target join field.
     * as: The name for the results.
     * pipeline: Optional pipeline to run on the foreign collection.
     * let: Optional variables to use in the pipeline field stages.
     */
    $lookup: {
      from: 'orders',
      localField: '_id',
      foreignField: 'user_id',
      as: 'orders_list',
      pipeline: [ //Aqui podemos hacer operaciones para la colección secundaria
        {
          /**
           * specifications: The fields to
           *   include or exclude.
           */
          $project: {
            'user_id': 0, // de la colección [orders]
          }
        }
      ],
    }
  },
  {
    /**
     * specifications: The fields to
     *   include or exclude.
     */
    $project: {
      'password': 0, //de la colección [users]
    }
  }
])

Resultado

[
  {
    "_id": {
      "$oid": "63dc480941d8383c5926809e"
    },
    "email": "[email protected]",
    "role": "admin",
    "social_accounts": [
      "twitter",
      "Facebook"
    ],
    "address": {
      "street": "cc 891",
      "city": "Bogota",
      "zip": "11011"
    },
    "shipping_adres": {
      "street": "cc 2342",
      "city": "Bogota",
      "zip": "22022"
    },
    "orders_list": [
      {
        "_id": {
          "$oid": "63dc5ccc617a08ee3ec6c213"
        },
        "date": "Thu Feb 02 2023 22:01:00 GMT-0300 (Brasilia Standard Time)",
        "item": [
          {
            "name": "camiseta",
            "price": 120,
            "qty": 2
          },
          {
            "name": "jeans",
            "price": 300,
            "qty": 1
          },
          {
            "name": "gorra",
            "price": 50,
            "qty": 1
          }
        ]
      },
      {
        "_id": {
          "$oid": "63dc5f4ad9dbf4f7eb40655c"
        },
        "date": "Thu Feb 02 2023 22:11:38 GMT-0300 (Brasilia Standard Time)",
        "item": [
          {
            "name": "short",
            "price": 23,
            "qty": 2
          }
        ]
      }
    ]
  }
]

Al momento de consultar por 1:n o n:n desde el punto de vista de base de datos debemos hacer estas búsquedas completas, pero cuando estamos en un producto real, puede o no verse como las búsquedas que hace el profesor