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.