Usando el Framework Aggregate de MongoDB en C#

Para un sistema que estoy haciendo (control bodega), tengo el siguiente esquema para los ingresos o egresos: 
Captura

De modo que si necesito obtener el historial del producto “Betún” lo hacía con un:

Movimiento m = _collection.find(Query.EQ("Detalle._idProducto", new ObjectId("identificador")));

Pero, obtenía TODO el detalle, incluyendo todos los demás productos ingresados en el movimiento junto al betún… Por lo que no era para nada eficiente. Es ahí cuando entra el famoso aggregation para hacerme la vida más simple.

En la shell, simple como esto:

db.Movimientos.aggregate(
  [
    {$unwind: "$Detalle"},
    {$match:
      {"Detalle._idProducto": ObjectId("51590da5a3e2c816101bb6f3")}
    }
  ]
)
  1. $unwind para decirle que separe todos los documentos bajo “Detalle” y los haga independientes.
  2. $match sobre el id del producto (bajo Detalle._idProducto). En este caso el id del betún.

Obteniendo lo que quiero Captura

Ahora lo movemos a C#

public IEnumerable<BsonDocument> getMovimientos(ObjectId producto)
{
  try
  {
    var unwind = new BsonDocument {{"$unwind", "$Detalle"}};
    var match = new BsonDocument {{"$match",new BsonDocument{{"Detalle._idProducto", producto}}}};

    var pipeline = new[] { unwind, match };
    var result = this._Collection.Aggregate(pipeline);
    return result.ResultDocuments;
  }
  catch (Exception e)
  {
    throw new Exception("Error al consultar Movimientos. \n"+e.Message);
  }
}

Y la ocupamos, por ejemplo, así (desde un cambio de item en combobox):

private void cmb_productos_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
  try
  {
    IEnumerable<MongoDB.Bson.BsonDocument> result = HM.getMovimientos(
      ((ClasesProClean.Producto)cmb_productos.SelectedItem).Id
    );
    foreach (var documento in result)
    {
      MessageBox.Show(documento.ToString());
    }
  }
  catch (Exception ex)
  {
    MessageBox.Show(ex.Message, "Error !", MessageBoxButton.OK, MessageBoxImage.Error);
  }
}

Eso sería todo🙂 Agregar que tengo problemas con $project … me da un error sobre _id , pero no es nada indispensable😀

Ahora, digamos que queremos mostrar el historial en una grilla, lo hacemos así:

//ARMAMOS LA GRILLA
DataGridTextColumn fecha = new DataGridTextColumn();
DataGridTextColumn movimiento = new DataGridTextColumn();
DataGridTextColumn producto = new DataGridTextColumn();
DataGridTextColumn cantidad = new DataGridTextColumn();
grid_historial.Columns.Add(fecha);
grid_historial.Columns.Add(movimiento);
grid_historial.Columns.Add(producto);
grid_historial.Columns.Add(cantidad);
fecha.Binding = new Binding("Fecha");
movimiento.Binding = new Binding("Movimiento");
producto.Binding = new Binding("Producto");
cantidad.Binding = new Binding("Cantidad");
fecha.Header = "Fecha";
movimiento.Header = "Tipo Movimiento";
producto.Header = "Producto";
cantidad.Header = "Cantidad";

//Enviamos los datos
foreach (var documento in result)
{
  grid_historial.Items.Add(
    new {
      Fecha = documento.GetValue("Fecha").AsDateTime.ToString(),
      Movimiento = (documento.GetValue("Ingreso").AsBoolean) ? "Ingreso" : "Egreso",
      Producto = documento.GetValue("Detalle").AsBsonDocument.GetValue("Producto"),
      Cantidad = documento.GetValue("Detalle").AsBsonDocument.GetValue("Cantidad")
    }
  );
} 

;) Captura

Fuentes:

Acerca de MaritoCares

Ingeniero Informático. Con tendencias a la programación en [C#, VB].NET, Java(Web principalmente...), PHP, JavaScript, algo mínimo de [ruby, python], y el clásico C.
Esta entrada fue publicada en C#, MongoDB, Tutoriales y etiquetada , . Guarda el enlace permanente.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s