在Meteor中,如何将查找查询的处理结果作为游标发布? [英] In Meteor how can I publish processed results of a find query as a cursor?

查看:77
本文介绍了在Meteor中,如何将查找查询的处理结果作为游标发布?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Meteor构建一个简单的消息传递应用程序。我正在努力解决未读消息的问题。我想返回一个列表,显示用户名(我不关心这个,请不要关注这方面,围绕反应性连接/复合等)和最新消息来自该用户我需要返回的内容因此,在下面的发布功能中,是最新的未读消息,显然只有每个唯一用户ID中的一个。

I'm building a simple messaging app with Meteor. The section I'm struggling with in unread messages. I would like to return a list, showing the username (I'm not concerned about this, please don't focus on this aspect, around reactive joins/ composites etc ) and the latest message from that user What I need to return therefore, in the publish function below, is the newest unread messages, BUT obviously only one from each unique user id.

这样做我试图在我的发布方法中操纵查找查询的结果,但是我不清楚如何操纵文档集而不破坏我在当前显示的反应性在下面的代码中,这是我到目前为止:

to do this im trying to manipulate the results of a find query in my publish method, but I'm unclear as to how to manipulate the document set without breaking the reactivity as I've shown in currently in the code below, this is what i've got so far :

Meteor.publish('unreadmessages', function() {

    if (!this.userId) {
        throw new Meteor.Error('denied', 'not-authorized');
    }

    var messageQuery, messages, userGroupQuery, userGroups;

    var self        = this;
    var user        = Meteor.users.findOne(self.userId);
    var userIdArr   = [self.userId]; // for use where queries require an array
    var contacts    = user.contacts;

    // get groups
    userGroupQuery  = Groups.find({
        $or : [
            { owner   : self.userId },
            { members : self.userId }
        ]
    }, { // Projection to only return the _id field
            fields : { _id:1 }
        }
    );

    userGroups = _.pluck(userGroupQuery.fetch(), '_id'); // create an array of id's

    messages = Messages.find({
        $or : [
            {
                $and : [
                    { participant : self.userId },
                    { userId : { $in : contacts } },
                    { readBy : { $nin : userIdArr } }
                ]
            },
            {
                $and : [
                    { groupId : { $in : userGroups } },
                    { readBy  : { $nin : userIdArr } }
                ]
            },
        ]
    });

     // TODO : also handle groups here
    uniqueMessages = _.uniq(messages.fetch(), function(msg) {
        return msg.userId;
    });

    return uniqueMessages; // obviously an array and not a cursor - meteor errors out.

});

我意识到我的下划线功能当然是在使用数据而不是返回数组而不是我需要的反应光标。我知道一个解决方案就是简单地选择消息ID然后在消息上运行另一个.find,但是还有另一个/更好/更有效/更自然的方式返回一个我正在寻找的结果集的游标吗?

i realize that my underscore function is of course working with, and indeed returning, an array rather than the reactive cursor i need. i know one solution would be to simply pluck the message ids and then run another .find on messages, but is there another / better / more efficient / more natural way to return a cursor with the result set i'm looking for?

推荐答案

这是最后的工作代码。这确实返回了一个游标,基本上我正在做的是从多个查询/修改中获取结果并将一组id引入最终的.find查询。

Heres the final working code. This does return a cursor as basically what I'm doing is taking the results from multiple queries / modifications and pumping a set of id's into the final .find query.

Meteor.publish('unreads', function() {
    if (!this.userId) {
        throw new Meteor.Error('denied', 'not-authorized');
    }

    // setup some vars
    var messageQuery,
        messages,
        userGroupQuery,
        userGroups,
        uniqeMsgIds;
    var self        = this;
    var user        = Meteor.users.findOne(self.userId);
    var userIdArr   = [self.userId]; // for use where queries require an array
    var contacts    = user.contacts;

    // get groups
    userGroupQuery  = Groups.find({
        $or : [
            { owner : self.userId },
            { members : self.userId }
        ]
    }, { // Projection to only return the _id field
            fields : { _id:1 }
        }
    );

    // create an array of group id's that belong to the user.
    userGroups = _.pluck(userGroupQuery.fetch(), '_id');

    messages = Messages.find({
        $or : [
            {  // unread direct messages
                $and : [
                    { participant : self.userId },
                    { userId : { $in : contacts } },
                    { readBy : { $nin : userIdArr } }
                ]
            },
            {  // unread group messages
                $and : [
                    { groupId : { $in : userGroups } },
                    { readBy : { $nin : userIdArr } }
                ]
            },
        ]
    }, { sort : { // put newest messages first
            time : -1
        }
    });

     // returns an array of unique documents based on userId or groupId
    uniqueMessages = _.uniq(messages.fetch(), function(msg) {
        if (msg.groupId) {
            return msg.groupId;
        }
        return msg.userId;
    });

    /*  Get the id's of all the latest unread messages
    (one per user or group) */
    uniqeMsgIds = _.pluck(uniqueMessages, '_id');

    /*  finally publish a reactive cursor containing
    one unread message(latest) for each user/group */
    return Messages.find({
        _id : { $in : uniqeMsgIds }
    });

});

这篇关于在Meteor中,如何将查找查询的处理结果作为游标发布?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆