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

Brug af kort/reducer til kortlægning af egenskaberne i en samling

OK, dette er lidt mere komplekst, fordi du bliver nødt til at bruge noget rekursion.

For at få rekursionen til at ske, skal du være i stand til at gemme nogle funktioner på serveren.

Trin 1:Definer nogle funktioner og sæt dem på serversiden

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

Trin 2:Definer kortet og reducer funktionerne

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

Trin 3:Kør kortet, og se på resultaterne

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

De resultater, du får, er:

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

Der er et åbenlyst problem her, vi tilføjer nogle uventede felter her:1. _id data2. .0 (på æg og type)

Trin 4:Nogle mulige rettelser

Til problem #1 rettelsen er forholdsvis nem. Du skal bare ændre map fungere. Skift dette:

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

til dette:

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

Problem #2 er lidt mere spidsfindig. Du ville have alle nøgler og teknisk "egg.0" er en gyldig nøgle. Du kan ændre m_sub at ignorere sådanne numeriske taster. Men det er også let at se en situation, hvor dette giver bagslag. Lad os sige, at du har et associativt array inde i et almindeligt array, så vil du have, at "0" skal vises. Jeg overlader resten af ​​den løsning til dig.



  1. MongoDB $ln

  2. Hvordan kan jeg dele MongoDB-samlinger mellem Meteor-apps?

  3. Fejl:Redis forbindelse til 127.0.0.1:6379 mislykkedes - tilslut ECONNREFUSED 127.0.0.1:6379

  4. Fjern et felt fra alle elementer i array i mongodb