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

查看:19
本文介绍了在 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天全站免登陆