example - Cómo usar variables en MongoDB Map-reduce map function
mongodb aggregation pipeline example (2)
Puede pasar datos globales de solo lectura en las funciones map-reduce usando el parámetro "scope" en el comando map-reduce. No está muy bien documentado, me temo.
Dado un documento
{_id:110000, groupings:{A:''AV'',B:''BV'',C:''CV'',D:''DV''},coin:{old:10,new:12}}
Mis especificaciones requieren la especificación de atributos para el mapeo y la agregación en tiempo de ejecución, ya que las agrupaciones que le interesan al usuario no se conocen desde el principio, sino que el usuario las especifica en el tiempo de ejecución.
Por ejemplo, un usuario especificaría [A, B] que causará el mapeo de las emisiones de
emit( {A:this.groupings.A,B:this.groupings.B},this.coin )
mientras que otro querría especificar [A, C] que causará el mapeo de las emisiones de
emit( {A:this.groupings.A,C:this.groupings.C},this.coin )
B / c las funciones del asignador y del reductor ejecutan el lado del servidor, y no tienen acceso a las variables del cliente, no he podido encontrar una forma de usar una tecla de mapa variable en la función del asignador.
Si pudiera hacer referencia a una lista de cosas para agrupar desde el alcance de la ejecución de la función de mapa, esto es muy sencillo. Sin embargo, b / c la función de mapeo termina obteniendo estos desde un alcance diferente, no sé cómo hacer esto, o si es posible.
Antes de comenzar a intentar construir dinámicamente script java para ejecutar a través del controlador, ¿alguien tiene una mejor sugerencia? ¿Tal vez una función de "grupo" manejará mejor este escenario?
Como señala @Dave Griffith, puede usar el parámetro scope
de la función mapReduce
.
Luché un poco para descubrir cómo pasarlo correctamente a la función porque, como señalaron otros, la documentación no es muy detallada. Finalmente, me di cuenta de que mapReduce
espera 3 parámetros:
- función de mapa
- reducir la función
- objeto con uno o más de los params definidos en el documento
Eventualmente, llegué al siguiente código en Javascript:
// I define a variable external to my map and to my reduce functions
var KEYS = {STATS: "stats"};
function m() {
// I use my global variable inside the map function
emit(KEYS.STATS, 1);
}
function r(key, values) {
// I use a helper function
return sumValues(values);
}
// Helper function in the global scope
function sumValues(values) {
var result = 0;
values.forEach(function(value) {
result += value;
});
return value;
}
db.something.mapReduce(
m,
r,
{
out: {inline: 1},
// I use the scope param to pass in my variables and functions
scope: {
KEYS: KEYS,
sumValues: sumValues // of course, you can pass function objects too
}
}
);