martes, 3 de septiembre de 2013

Como eliminar un elemento de array usando aggregation en MongoDB

No hace mucho os explicamos como eliminar un elemento de un array usando javascript, hoy vamos a complicarlo un poco mas y vamos a explicar paso a paso como eliminar el mayor o menor elemento de un array por cada documento en nuestra colección, usando aggregation en MongoDB. Viendo que aun cuesta adaptarse a las consultas en NoSQL, poco a poco vamos a ir haciendo ejemplos como realizar algunas de ellas para ir practicando.

Para realizar este ejercicios descarguense el fichero ventas.json de ejemplo e importenlo de la siguiente forma:
mongoimport -d supermercado -c ventas < ventas.json
Disponemos de una colección con la venta de artículos de cada empleado, en la que los documentos tienen el siguiente esquema:

Esquema de base de datos por HispaBigData

"_id" : 0,
"vendedor" : "Manuel Sanchez",
"articulos" : [
 {
  "articulo" : "fregona",
  "pvp" : 14.25
 },
 {
  "articulo" : "fregona",
  "pvp" : 17.75
 },
 {
  "articulo" : "escoba",
  "pvp" : 8.75
 }
 ]
}
El ejercicio consistirá en lo siguiente: Por cada vendedor que tenemos en nuestra colección, vamos a eliminar el articulo más caro que haya vendido, para ello primero debemos conocer cual es el precio del mayor articulo por vendedor, esto lo conseguimos realizando lo siguiente:
resultado = db.ventas.aggregate( [ { "$unwind": "$articulos" } , 
    { "$group": { '_id':'$_id' , 'maxprecio': { '$max': "$articulos.pvp" } } } ] );
Con la función $unwind conseguimos tener un documento por cada elemento del array artículos, lo siguiente que realizamos es agrupar por _id, ya que queremos realizar la operación por cada vendedor, y por el articulo de mayor precio esto, lo conseguimos con la función $max. El resultado de esta consulta lo vamos a guardar en la variable resultado.

Lo siguiente es recorrernos cada uno de los _id de la variable resultado e ir buscando cada documento que coincida con dicho _id para eliminar, con la funcion $pull, el articulo de mayor precio que exista en el array articulos y que coincida con el que se encuentra en la variable resultado.
for (var i = 0; i < resultado['result'].length; i++){
 { db.ventas.update( { '_id': resultado['result'][i]['_id'] }, 
  { '$pull': { 'articulos': { 'pvp': resultado['result'][i]['maxprecio']} } } ); }
}
Como podéis observar en el siguiente vendedor ya no aparece la fregona vendida por 17.75


Os propongo el siguiente ejercicio, con la misma colección, eliminar de cada vendedor las fregonas de menor precio que hayan vendido. Para ello, revisen la función $match.

No hay comentarios:

Publicar un comentario en la entrada