2016-11-15 7 views
0

J'ai besoin de créer une publication, ce qui me donne un ensemble de documents de la collection. Ici vous pouvez voir, la façon dont les documents sont liés les uns aux autres:MongoDB: Comment obtenir le document principal et tous les ancêtres

{ 
    "_id" : "peRuJcPMDzZgTvWSX", 
    "author" : "author", 
    "type" : "article", 
    "parent" : "mnfTFfZ7Fqcu6ZJ7T", 
    "ancestors" : [ "hbSycmNNvmdqvpchX", "mnfTFfZ7Fqcu6ZJ7T" ] 
} 
{ 
    "_id" : "mnfTFfZ7Fqcu6ZJ7T", 
    "article" : "article", 
    "parent" : "hbSycmNNvmdqvpchX", 
    "ancestors" : [ "hbSycmNNvmdqvpchX" ] 
} 
{ 
    "_id" : "hbSycmNNvmdqvpchX", 
    "title" : "title", 
    "ancestors" : [ ] 
} 

Alors ce que je sais est l'ID du premier document et j'ai besoin aussi tous les ancêtres dans la publication.

Meteor.publish('list', function(id) { 
    check(id, String); 
    return Collection.find({}); // WRONG: gives me ALL documents 
    return Collection.find({ _id: id }) // WRONG: gives me only the first document (main) 
    // NEEDED: Main document and all ancestors 
}); 
+0

On dirait que vous aurez besoin de retirer le document principal avec '{_id: id} 'et ensuite tirer les ancêtres de cette propriété –

Répondre

1

Vous aurez besoin de faire un premier .findOne() revenir ensuite un tableau de curseurs:

Meteor.publish('list', function(id) { 
    check(id, String); 
    const ancestors = Collection.findOne(id).ancestors; 
    if (ancestors){ 
    return [ Collection.find(id), Collection.find({_id: {$in: ancestors}})]; 
    } else { 
    return Collection.find(id); 
    } 
}); 

Vous pouvez aussi le faire avec un .find() unique à l'aide d'un $or mais ce serait probablement plus lente.

+0

Il manque un') 'dans' ... ancêtres}}] '. Et ne devrait-il pas être une virgule dans le tableau, au lieu d'un point-virgule? – user3142695

+0

Absolument correct! Et maintenant corrigé. –

0

Vous pouvez cette publish-composite de publier un rejoindre relation dans Meteor:

Meteor.publishComposite('list', function(id) { 
    // checking here ... 

    return { 
    find() { 
     return Collection.find(id); 
    }, 
    children: [{ 
     find(doc) { 
     return Collection.find({ 
      _id: { 
      $in: doc.ancestors 
      } 
     }); 
     }, 
    }], 
    }; 
}); 

Ce paquet fait en sorte que votre publication est réactif, par exemple Si la valeur de ancestors change, les données publiées sur le client doivent être mises à jour pour refléter ce changement. Si vous utilisez juste findOne dans la publication pour obtenir la liste ancestors, les données envoyées au client ne seront pas mis à jour lorsque la valeur de ancestors changement