MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Utilisation de map/reduce pour mapper les propriétés dans une collection

OK, c'est un peu plus complexe car vous aurez besoin d'utiliser de la récursivité.

Pour que la récursivité se produise, vous devez pouvoir stocker certaines fonctions sur le serveur.

Étape 1 :définissez certaines fonctions et placez-les côté serveur

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

Étape 2 :définir la carte et réduire les fonctions

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

Étape 3 :exécutez la réduction de la carte et examinez les résultats

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

Les résultats que vous obtiendrez sont :

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

Il y a un problème évident ici, nous ajoutons ici des champs inattendus :1. les données _id2. le .0 (sur l'oeuf et le type)

Étape 4 :Quelques correctifs possibles

Pour le problème n° 1 la solution est relativement facile. Modifiez simplement la map une fonction. Modifiez ceci :

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

à ceci :

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

Problème 2 est un peu plus risqué. Tu voulais tout clés et techniquement "egg.0" est une clé valide. Vous pouvez modifier m_sub pour ignorer ces touches numériques. Mais il est également facile de voir une situation où cela se retourne contre nous. Supposons que vous ayez un tableau associatif à l'intérieur d'un tableau régulier, alors vous voulez que "0" apparaisse. Je vous laisse le reste de cette solution.