2014-07-24 3 views
0

j'ai deux MongoDB collections: La première est une collection qui comprend des informations de fréquence pour différents identifiants et est représenté (forme tronquée) ci-dessous:MongoDB - Comment utiliser MapReduce pour fusionner une valeur d'une collection dans une autre collection sur plusieurs clés d'une seconde collection?

[ 
    { 
     "_id" : "A1", 
     "value" : 19 
    }, 
    { 
     "_id" : "A2", 
     "value" : 6 
    }, 
    { 
     "_id" : "A3", 
     "value" : 12 
    }, 
    { 
     "_id" : "A4", 
     "value" : 8 
    }, 
    { 
     "_id" : "A5", 
     "value" : 4 
    }, 
    ... 
] 

La deuxième collection est plus complexe et contient des informations pour chaque _id énumérés dans la première collection (il est appelé frequency_collection_id dans la deuxième collection), mais frequency_collection_id peut être à l'intérieur de deux listes (info.details_one et info.details_two) pour chaque enregistrement:

[ 
    { 
     "_id" : ObjectId("53cfc1d086763c43723abb07"), 
     "info" : { 
      "status" : "pass", 
      "details_one" : [ 
       { 
        "frequency_collection_id" : "A1", 
        "name" : "A1_object_name", 
        "class" : "known" 
       }, 
       { 
        "frequency_collection_id" : "A2", 
        "name" : "A2_object_name", 
        "class" : "unknown" 
       } 
      ], 
      "details_two" : [ 
       { 
        "frequency_collection_id" : "A1", 
        "name" : "A1_object_name", 
        "class" : "known" 
       }, 
       { 
        "frequency_collection_id" : "A2", 
        "name" : "A2_object_name", 
        "class" : "unknown" 
       } 
      ], 
     } 
    } 
    ... 
] 

Wha t Je cherche à faire, est de fusionner les informations de fréquence (de la première collection) dans la deuxième collection, en effet la création d'une collection qui ressemble à:

[ 
    { 
     "_id" : ObjectId("53cfc1d086763c43723abb07"), 
     "info" : { 
      "status" : "pass", 
      "details_one" : [ 
       { 
        "frequency_collection_id" : "A1", 
        "name" : "A1_object_name", 
        "class" : "known", 
        **"value" : 19** 
       }, 
       { 
        "frequency_collection_id" : "A2", 
        "name" : "A2_object_name", 
        "class" : "unknown", 
        **"value" : 6** 
       } 
      ], 
      "details_two" : [ 
       { 
        "frequency_collection_id" : "A1", 
        "name" : "A1_object_name", 
        "class" : "known", 
        **"value" : 19** 
       }, 
       { 
        "frequency_collection_id" : "A2", 
        "name" : "A2_object_name", 
        "class" : "unknown", 
        **"value" : 6** 
       } 
      ], 
     } 
    } 
    ... 
] 

Je sais que cela devrait être possible avec MongoDB de MapReduce fonctions, mais tous les exemples que j'ai vus sont soit trop minimes pour ma structure de collection, soit répondent à des questions différentes de celles que je recherche.

Est-ce que quelqu'un a des pointeurs? Comment puis-je fusionner mes informations de fréquence (de ma première collection) dans les enregistrements (à l'intérieur de mes deux listes dans chaque enregistrement de la deuxième collection)?

Je sais que cela est plus ou moins un JOIN, qui MongoDB ne supporte pas, mais de ma lecture, il semble que c'est un excellent exemple de MapReduce. J'apprends le Mongo du mieux que je peux, alors s'il vous plaît pardonnez-moi si ma question est trop naïve.

Répondre

1

Comme toutes les opérations MongoDB, un MapReduce fonctionne toujours sur une seule collection et ne peut pas obtenir d'informations d'un autre. La première étape consiste donc à vider les deux collections en une seule. Vos documents ont des _id différents, donc ça ne devrait pas être un problème pour eux de coexister dans la même collection.

Ensuite vous faites un MapReduce où la carte fonction emit des deux types de documents pour leur key commune, qui est leur ID de fréquence.

Votre réduire fonction recevra alors un tableau de deux documents pour chaque clé: les deux documents que vous avez reçus. Vous n'avez alors qu'à fusionner ces deux documents en un seul. Gardez à l'esprit que la fonction de réduction peut recevoir ces deux documents dans n'importe quel ordre. Il peut aussi arriver qu'il soit appelé pour un résultat partiel (un seul des deux documents) ou pour un résultat déjà complété. Vous devez gérer ces cas avec élégance! Une bonne implémentation pourrait être de créer un nouvel objet, puis d'itérer les documents d'entrée en copiant tous les champs pertinents existants avec leurs valeurs dans le nouvel objet, de sorte que l'objet résultant est un amalgame des documents d'entrée.

Questions connexes