es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Agregación en MongoDB con proyección dinámica.

Estoy estudiando MongoDB con el controlador Nodejs en Typescript; me gustaría recuperar subdocumentos de documentos con una proyección “dinámica”; esto se debe hacer con una matriz que enumere los campos deseados:

{ 
    "id" : ObjectId("6006be017fdd3b1018e0f533"), 
    "name" : "Cindy", 
    "surname" : "Red", 
    "age" : 30.0, 
    "various" : {
        "aaa1" : "111", 
        "bbb2" : "222"
    }
}
{ 
    "id" : ObjectId("6006be0b7fdd3b1018e0f534"), 
    "name" : "Valentina", 
    "surname" : "Green", 
    "age" : 30.0, 
    "various" : {
        "ccc3" : "333", 
        "ddd4" : "444"
    }
}

// Este fragmento de código ejecuta la consulta:
const arrayValues = [“$various”];
const result = await myConnectedClient
.db(“ZZZTESTALL”)
.collection(“mycollection01″)
.aggregate([
{ $project: { _id: 0, arrayValues } },
]);

Resultado:

{
  _id: 6006be017fdd3b1018e0f533,
  arrayValues: [ { aaa1: '111', bbb2: '222' } ]
}
{
  _id: 6006be0b7fdd3b1018e0f534,
  arrayValues: [ { ccc3: '333', ddd4: '444' } ]
}

pero me gustaría obtener este resultado:

{
  various: { aaa1: '111', bbb2: '222' }
}
{
  various:  { ccc3: '333', ddd4: '444' } 
}

Gracias.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para obtener el resultado deseado, debes modificar la proyección para usar el operador $arrayToObject. Aquí tienes un ejemplo de código actualizado:

    const arrayValues = ['$various'];
    const result = await myConnectedClient
      .db('ZZZ_TEST_ALL')
      .collection('my_collection_01')
      .aggregate([
        {
          $project: {
            _id: 0,
            various: { $arrayToObject: [[{ k: '$$this', v: `$$ROOT.${'$$this'}` } for '$various']] }
          },
        },
      ])
      .toArray();
    

    Esto devolverá el siguiente resultado deseado:

    [
      { "various": { "aaa1": "111", "bbb2": "222" } },
      { "various": { "ccc3": "333", "ddd4": "444" } } 
    ]
    

    Explicación:

    • El operador $arrayToObject convierte un array de pares clave-valor en un objeto, donde las claves y los valores se obtienen de los elementos del array. En este caso, el array consta de claves generadas a partir del campo $various y valores obtenidos utilizando $$ROOT para hacer referencia al documento actual y al campo $various como el subdocumento anidado.
    • Para crear el array de pares clave-valor que $arrayToObject espera, utilizamos la sintaxis for...in para iterar sobre el campo $various y generar un elemento de array para cada par clave-valor, siendo la clave representada como un literal de cadena y el valor referido utilizando $$ROOT.${'$$this'}, donde $$this hace referencia a la clave actual que se está procesando. Finalmente, envolvemos el array en otro array para satisfacer la sintaxis de $arrayToObject, que espera un array de arrays.
    • Luego, le damos al campo de objeto resultante el nombre various utilizando el operador $project.

Comments are closed.