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的数据不会更新
我需要创建一个出版物,它为我提供了集合中的一组文档。在这里您可以看到文档之间的关系:
{
"_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
的值改变