sql >> Base de Datos >  >> NoSQL >> MongoDB

Usar map/reduce para mapear las propiedades en una colección

Bien, esto es un poco más complejo porque necesitarás usar algo de recursividad.

Para que ocurra la recurrencia, deberá poder almacenar algunas funciones en el servidor.

Paso 1:definir algunas funciones y ponerlas del lado del servidor

isArray = function (v) {
  return v && typeof v === 'object' && typeof v.length === 'number' && !(v.propertyIsEnumerable('length'));
}

m_sub = function(base, value){
  for(var key in value) {
    emit(base + "." + key, null);
    if( isArray(value[key]) || typeof value[key] == 'object'){
      m_sub(base + "." + key, value[key]);
    }
  }
}

db.system.js.save( { _id : "isArray", value : isArray } );
db.system.js.save( { _id : "m_sub", value : m_sub } );

Paso 2:definir el mapa y reducir funciones

map = function(){
  for(var key in this) {
    emit(key, null);
    if( isArray(this[key]) || typeof this[key] == 'object'){
      m_sub(key, this[key]);
    }
  }
}

reduce = function(key, stuff){ return null; }

Paso 3:ejecuta el mapa reduce y mira los resultados

mr = db.runCommand({"mapreduce" : "things", "map" : map, "reduce" : reduce,"out": "things" + "_keys"});
db[mr.result].distinct("_id");

Los resultados que obtendrás son:

["_id", "_id.isObjectId", "_id.str", "_id.tojson", "egg", "egg.0", "foo", "foo.bar", "foo.bar.baaaar", "hello", "type", "type.0", "type.1"]

Aquí hay un problema obvio, estamos agregando algunos campos inesperados aquí:1. el _id datos2. el .0 (en huevo y tipo)

Paso 4:Algunas soluciones posibles

Para problema #1 la solución es relativamente fácil. Simplemente modifique el map función. Cambia esto:

emit(base + "." + key, null); if( isArray...

a esto:

if(key != "_id") { emit(base + "." + key, null); if( isArray... }

Problema #2 es un poco más arriesgado. Querías todo teclas y técnicamente "egg.0" es una clave válida. Puede modificar m_sub para ignorar dichas teclas numéricas. Pero también es fácil ver una situación en la que esto resulte contraproducente. Digamos que tiene una matriz asociativa dentro de una matriz normal, entonces quiere que aparezca ese "0". Dejaré el resto de esa solución en tus manos.