MongoDB: 如何获取主文档和所有祖先

MongoDB: How to get main document and all ancestors

我需要创建一个出版物,它为我提供了集合中的一组文档。在这里您可以看到文档之间的关系:

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

所以我知道的是第一个文档的 ID,我还需要出版物中的所有祖先。

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

你需要先做一个.findOne(),然后return一个游标数组:

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

您也可以使用单个 .find() 使用 $or 来执行此操作,但这可能会更慢。

您可以 publish-composite 在 Meteor 中发布 join 关系:

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

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

这个包确保你的发布是反应性的,例如如果 ancestors 的值发生变化,则应更新发布到客户端的数据以反映该变化。如果只是在publication中使用findOne获取ancestors列表,那么当ancestors的值改变

时,发送给client的数据不会更新