MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Utilizzo di map/reduce per mappare le proprietà in una raccolta

OK, questo è un po' più complesso perché dovrai usare un po' di ricorsione.

Per fare in modo che la ricorsione avvenga, dovrai essere in grado di memorizzare alcune funzioni sul server.

Fase 1:definisci alcune funzioni e mettile lato server

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 } );

Fase 2:definisci la mappa e riduci le funzioni

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; }

Fase 3:esegui la riduzione della mappa e guarda i risultati

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

I risultati che otterrai sono:

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

C'è un problema evidente qui, stiamo aggiungendo alcuni campi imprevisti qui:1. i dati _id2. il .0 (su uovo e tipo)

Fase 4:alcune possibili soluzioni

Per problema n. 1 la soluzione è relativamente facile. Basta modificare la map funzione. Cambia questo:

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

a questo:

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

Problema n. 2 è un po' più rischioso. Volevi tutti chiavi e tecnicamente "egg.0" è una chiave valida. Puoi modificare m_sub ignorare tali tasti numerici. Ma è anche facile vedere una situazione in cui questo si ritorce contro. Supponiamo che tu abbia un array associativo all'interno di un array regolare, quindi vuoi che appaia "0". Lascerò a te il resto della soluzione.