2010-05-12 5 views
20

J'ai besoin de quelque chose d'un peu plus complexe que les exemples dans les docs MongoDB et je ne peux pas sembler pouvoir envelopper ma tête autour d'elle.Utiliser la carte de MongoDB/réduire à "group by" deux champs

Dire que j'ai une collection d'objets de la forme {date: "2010-10-10", type: "EVENT_TYPE_1", user_id: 123, ...}

Maintenant, je veux obtenir quelque chose de similaire à un groupe SQL par requête, regroupant à la fois sur la date et le type. Autrement dit, je veux le nombre d'événements de chaque type dans chaque jour. Aussi, je voudrais le rendre unique par user_id, ie. Si un utilisateur a plus d'événements dans la même journée, comptez-le une seule fois. J'essaye de faire ceci avec map/reduce. J'essaye de faire ceci avec map/reduce.

Je ne

db.logs.mapReduce( 
    function() { 
     emit(this.type, 1); 
    }, 
    function(k, vals) { 
     var total = 0; 
     for (var i = 0; i < vals.length; i++) 
      total += vals[i]; 
     return total; 
    } 
) 

qui bien des groupes par type, mais maintenant, comment puis-je groupe par date en même temps? Semble la clé dans emit() ne peut pas être un tableau (j'ai pensé à faire emit([this.date, this.type], 1)). Aussi, comment puis-je assurer l'unicité de l'utilisateur?

Je ne fais que commencer avec MongoDB et j'ai toujours du mal à comprendre les concepts de base. En outre, il n'y a pas beaucoup de documentation disponible là-bas. Toute aide d'utilisateurs plus expérimentés est appréciée. Merci!

+0

couchdb peut faire des tableaux en tant que clés, il suffit de dire – dominic

Répondre

19

J'ai trouvé une très bonne solution dans le livre de recettes MongoDB (je ne connaissais pas cette ressource auparavant).

http://cookbook.mongodb.org/patterns/unique_items_map_reduce/

En fait, au groupe par plusieurs clés, vous utilisez un dict, pas une liste (comme je l'ai essayé). De plus, pour obtenir des résultats uniques, vous devez effectuer deux passes de carte/réduction.

+3

Le lien ne fonctionne pas. Toute personne intéressée à regrouper/émettre plus de quelques champs peut utiliser la structure suivante: emit ({date: this.date, type: this.type}, 1) –