readbyid - mongodb gridfs
¿MongoDB map/reduce en múltiples colecciones? (2)
Primero, el fondo. Solía tener logs
recopilación y usé map / reduce para generar varios informes. La mayoría de estos informes se basaron en datos de un solo día, por lo que siempre tuve una condición d: SOME_DATE
. Cuando la colección de logs
hizo extremadamente grande, la inserción se hizo extremadamente lenta (más lenta que la aplicación que estábamos monitoreando generaba registros), incluso después de descartar muchos índices. Así que decidimos tener los datos de cada día en una recopilación separada - logs_YYYY-mm-dd
- de esa manera los índices son más pequeños, y ni siquiera necesitamos un índice en la fecha. Esto es genial ya que la mayoría de los informes (por lo tanto, mapear / reducir) están en datos diarios. Sin embargo, tenemos un informe en el que tenemos que cubrir varios días.
Y ahora la pregunta. ¿Hay una manera de ejecutar un mapa / reducir (o más precisamente, el mapa) sobre múltiples colecciones como si fuera solo una?
Se puede llamar a una función de reducción una vez, con una clave y todos los valores correspondientes (pero solo si hay varios valores para la clave; no se llamará en absoluto si solo hay 1 valor para la clave).
También se puede llamar varias veces, cada vez con una clave y solo con un subconjunto de los valores correspondientes , y la reducción previa de los resultados para esa clave. Este escenario se llama re-reducir . Para poder admitir reducciones, su función de reducción debe ser idempotent .
Hay dos características clave en una función de reducción idempotente:
- El valor de retorno de la función de reducción debe estar en el mismo formato que los valores que toma. Por lo tanto, si su función de reducción acepta una matriz de cadenas, la función debe devolver una cadena. Si acepta objetos con varias propiedades, debe devolver un objeto que contenga esas mismas propiedades. Esto asegura que la función no se rompa cuando se llama con el resultado de una reducción previa.
- No haga suposiciones basadas en la cantidad de valores que toma. No se garantiza que el parámetro de
values
contenga todos los valores para la clave dada. Por lo tanto, utilizarvalues.length
en los cálculos es muy arriesgada y debe evitarse.
Actualización: los dos pasos a continuación no son necesarios (o incluso posibles, no los he comprobado) en las versiones más recientes de MongoDB. Ahora puede manejar estos pasos por usted, si especifica una colección de salida en las options reducción de mapa:
{ out: { reduce: "tempResult" } }
Si su función de reducción es idempotente, no debería tener problemas para reducir varias colecciones. Solo reduzca los resultados de cada colección:
Paso 1
Ejecute map-reduce en cada colección requerida y guarde los resultados en una sola colección temporal. Puede almacenar los resultados utilizando una función de finalización :
finalize = function (key, value) {
db.tempResult.save({ _id: key, value: value });
}
db.someCollection.mapReduce(map, reduce, { finalize: finalize })
db.anotherCollection.mapReduce(map, reduce, { finalize: finalize })
Paso 2
Ejecute otro map-reduce en la colección temporal, usando la misma función de reducción . La función de mapa es una función simple que selecciona las claves y los valores de la colección temporal:
map = function () {
emit(this._id, this.value);
}
db.tempResult.mapReduce(map, reduce)
Este segundo map-reduce es básicamente una reducción y debería darle los resultados que necesita.
map-reduce
método de map-reduce
. Aquí hay un ejemplo.
var mapemployee = function () {
emit(this.jobid,this.Name);};
var mapdesignation = function () {
emit(this.jobid, this.Designation);};
var reduceF = function(key, values) {
var outs = {Name:null,Designation: null};
values.forEach(function(v){
if(outs.Name ==null){
outs.Name = v.Name }
if(outs.Name ==null){
outs.Nesignation = v.Designation}
});
return outs;
};
result = db.employee.mapReduce(mapemployee, reduceF, {out: {reduce: ''output''}});
result = db.designation.mapReduce(mapdesignation,reduceF, {out: {reduce: ''output''}});
Referencia: http://www.itgo.me/a/x3559868501286872152/mongodb-join-two-collections