meteor merging cursors of same collection

2019-04-10 02:07发布

问题:

In my social app(like as FB) I have a strange need to merge two cursors of the same collection users in one publish!

Meteor server print this error: "Publish function returned multiple cursors for collection users".

Maybe this can not be done in Meteor 0.7.2, perhaps I'm mistaken approach. But I have seen the structure of a cursor is pretty simple as I could make a simple array merge and return back a Cursor?

CLIENT

Meteor.subscribe('friendById', friend._id, function() {
    //here show my friend data and his friends
});

SERVER

//shared functions in lib(NOT EDITABLE)
getUsersByIds = function(usersIds) {
    return Meteor.users.find({_id:  {$in: usersIds} },
                            {
                                fields: {   // limited fields(FRIEND OF FRIEND)
                                    username: 1,
                                    avatar_url: 1
                                }
                            });
};
getFriendById = function(userId) {
    return Meteor.users.find(userId,
                            {
                                fields: {   // full fields(ONLY FOR FRIENDS)
                                    username: 1,
                                    avatar_url: 1,
                                    online: 1,
                                    favorites: 1,
                                    follow: 1,
                                    friends: 1
                                }
                            });
};

Meteor.publish('friendById', function(userId) { //publish user data and his friends

    if(this.userId && userId)
    {
        var userCur = getFriendById(userId),
            userFriends = userCur.fetch()[0].friends,
            retCurs = [];

        //every return friend data
        retCurs.push( userCur );

        //if user has friends! returns them but with limited fields:

        if(userFriends.length > 0)
            retCurs.push( getUsersByIds(userFriends) );

        //FIXME ERROR "Publish function returned multiple cursors for collection users"

        return retCurs;     //return one or more cursor
    }
    else
        this.ready();
});

回答1:

See bold red text in the documentation:

If you return multiple cursors in an array, they currently must all be from different collections.

There is the smart-publish package which adds this ability to use on publish to manage multiple cursors on the same collection. It is relatively new.

Either that or manually manage the cursors by using 'this.added', 'this.removed', and 'this.changed' inside the publish.



回答2:

SOLUTION

Meteor.publish('friendById', function(userId) {

    if(this.userId && userId)
    {
        var userCur = getFriendById(userId),  //user full fields
            userData = userCur.fetch()[0],
            isFriend = userData.friends.indexOf(this.userId) != -1,
            retCurs = [];

        //user and his friends with limited fields
        retCurs.push( getUsersByIds( _.union(userId, userData.friends) ));

        if(isFriend)
        {
            console.log('IS FRIEND');

            this.added('users',userId, userData);   //MERGE full fields if friend
            //..add more fields and collections in reCurs..
        }

        return retCurs;
    }
    else
        this.ready();
});