递归发布 - 角度流星

时间:2015-07-28 20:25:16

标签: mongodb meteor angular-meteor

我想要为每个评论加载一个主题,25个评论和最多5个子评论,在每个评论/子评论上递归重复,直到找到所有相关评论。

我目前正在使用angular指令以递归方式订阅并在评论有子项时添加到本地集合。它运作得很好,但是在加载最初的25条评论,加载他们的孩子,然后加载他们的孩子等之间存在一些滞后(预期)。

此问题在一次只加载页面时不会出现问题。当使用无限滚动并增加最初的25个注释限制时,它会成为一个问题。它将导致页面在子注释消失时上下跳动,并在再次加载后重新出现。

我想知道如何在发送给本地客户之前递归查找所有评论,这样我就不需要为每个主题进行多次往返。

我在ck-gaming.com

加载了一个演示版

如果你滚动到底部它会加载更多,当你将子注释重新加载到页面中时,你会看到它全部跳过。

我能想到的两个选项是使用解决方案在加载页面之前等待所有集合,或者使用递归发布将它们全部放在首位。

思考?想法?

好的,我的第一次尝试,如果可能,我想要一些想法。

对于发布,我决定使用publish-composite更容易从同一个集合发布。

我写的出版物:

Meteor.publishComposite('oneDiscussion', function (slug, options) {

var query = {};
query.find = function () {
    return Discussions.find({ slug: slug }, { limit: 1 });
};

var mainChildQuery = Comments.find({ slug: slug }, { limit: 1 });

query.children = [];
query.children[0] = {};
query.children[0].find = function (discussion) {
    return mainChildQuery;
};
query.children[0].children = [];
query.children[0].children[0] = {};
query.children[0].children[0].find = function (comment) {
    return Meteor.users.find({ _id: comment.author.id }, { limit: 1, fields: { profile: 1, roles: 1, createdAt: 1, username: 1 } });
};
query.children[0].children[1] = {};
query.children[0].children[1].find = function (parent) {
    Counts.publish(this, 'numberOfComments', Comments.find(
        { parent_id: parent._id }
        ), { noReady: true });
    console.log(options)
    return Comments.find({ parent_id: parent._id }, options);
};

//  var parentQuery = Comments.find({ slug: slug });
var parent = mainChildQuery.fetch();
var children = Comments.find({ parent_id: parent[0]._id }, { limit: 25 }).fetch();

var childrenIds = _.pluck(children, '_id');


var getChildren = function (children_ids, thisParent) {

    var i = 0;
    thisParent.children = [];

    var recursive = function getEm(children, parent) {
        _.each(children, function (id) {

            //              parent.children[i] = new Children(id);
            var query = Comments.find({ parent_id: id }, { limit: 5, sort: { date: -1 } });
            parent.children[i] = {
                find: function () {
                    return Comments.find({ parent_id: id }, { limit: 5, sort: { date: -1 } });
                }
            };


            var children1 = query.fetch();
            var newChildrenIds = _.pluck(children1, '_id');
            i++;
            if (newChildrenIds.length > 0) {
                getEm(newChildrenIds, parent);
            }
        });
    }

    recursive(children_ids, thisParent);

};

getChildren(childrenIds, query.children[0].children[1]);
return query;

});

到目前为止似乎工作正常,虽然在我的桌面上运行它并不像我认为的那样高效。我将对其进行部署,看看是否存在差异。我回家后会更新并可以更新实际网站。如果有人发现我写的东西有问题,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

我想出了我认为最好的解决方案。我改进了上面的功能,到目前为止,我真的很享受结果。

这是发布功能:

Meteor.publishComposite('comments', function (item_id, options) {
    /**
     * TODO: Add query to find a user for each comment.
     */
    /**
     * Start building our query.
     * Add the latest 25 (depending on options) child comments of the viewed item
     * to the query.
     */
    var query = {
        find: function () {
            return Comments.find({ parent_id: item_id }, options);
        }
    };
    // Query the database for the first 25? comments, we'll need their _id's
    var mainChildren = Comments.find({ parent_id: item_id }, options).fetch();
    // pluck the id's from the initial comments
    var mainChildrenIds = _.pluck(mainChildren, '_id');

    /**
     * Builds the remaining query based on the id's plucked from the children
     *  above.
     * @param childrens_id The id's we just plucked from the above query
     * @param thisParent This is the parent query
     */
    var getChildren = function (children_ids, parentQuery) {
        // initiate i to 0
        var i = 0;
        // add a child array to the current parent query.
        parentQuery.children = [];
        var recursive = function getem(children, parent) {
            _.each(children, function (id) {
                var query = Comments.find({ parent_id: id }, { limit: 5, sort: { date: 1 } });
                parent.children[i] = {
                    find: function () {
                        return query;
                    }
                };
                var children1 = query.fetch();
                var newChildrenIds = _.pluck(children1, '_id');
                i++;
                if (newChildrenIds.length > 0) {
                    getem(newChildrenIds, parent);
                }
            });
        };
        // recursively build the query if there are children found.
        recursive(children_ids, parentQuery);
    };
    // initiate the query build function
    getChildren(mainChildrenIds, query);
    return query;
});

我创建了一个可以在GitHub上发布的示例应用here

您可以在meteorpad here

上查看它

它的作用

所有函数都是构建publishComposite查询,递归循环遍历子ID,只要有子id即可。当没有更多的孩子时,它会停止。

使用

您想要一个包含parent_id字段的评论集(或任何您正在嵌套的集合)。此字段将填充父项目ID,父项目ID(如果使用评论/评论创建商店)。父帖id当然是您评论的评论或帖子。有关详细信息,请参阅示例。