Javascript 在Meteor中,如何将find查询的处理结果发布为游标?
我正在用Meteor构建一个简单的消息应用程序。我在未读邮件中挣扎的部分。我想返回一个列表,显示用户名(我不关心这一点,请不要关注这一方面,围绕反应性连接/复合等),并且该用户的最新消息因此,在下面的发布功能中,我需要返回的是最新的未读消息,但是显然每个唯一的用户id只有一个 为此,我试图在我的发布方法中操纵find查询的结果,但我不清楚如何在不破坏反应性的情况下操纵文档集,正如我目前在下面的代码中所示,这是我目前得到的:Javascript 在Meteor中,如何将find查询的处理结果发布为游标?,javascript,meteor,underscore.js,meteor-publications,Javascript,Meteor,Underscore.js,Meteor Publications,我正在用Meteor构建一个简单的消息应用程序。我在未读邮件中挣扎的部分。我想返回一个列表,显示用户名(我不关心这一点,请不要关注这一方面,围绕反应性连接/复合等),并且该用户的最新消息因此,在下面的发布功能中,我需要返回的是最新的未读消息,但是显然每个唯一的用户id只有一个 为此,我试图在我的发布方法中操纵find查询的结果,但我不清楚如何在不破坏反应性的情况下操纵文档集,正如我目前在下面的代码中所示,这是我目前得到的: Meteor.publish('unreadmessages', fun
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,然后运行另一个。在消息上查找,但是否有其他/更好/更有效/更自然的方法返回带有我要查找的结果集的光标?您可以使用并使其成为反应式。在添加的上,可以添加字段。我正在使用这个惊人的软件包:,它为您节省了时间
使用分页,否则您将无法享受性能。下面的代码确实发布了一个反应性光标,这是一个可行的解决方案,但我想我的问题的关键是,是否有更好的方法来操作最后一条消息的结果集。查找仍然发布反应性光标(我沿着cursor.forEach或.map的思路思考,但我不确定如何实现这一点)
基本上-有更好的方法吗:
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 };
});
});
这是最终的工作代码。这确实会返回一个游标,因为基本上我所做的是获取多个查询/修改的结果,并将一组id输入final.find查询
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.method。一个方法可以向客户端返回一个数组。另外,Messages.find()将已经返回一组唯一的消息。为了理解您调用q.uniq的原因,显示一些来自消息的示例文档会很有帮助。我很清楚,我现在看到的不是反应性的,但我希望它返回一个光标,我想一定是在发布函数之后,其次,为了解释我希望返回最新的u为每个用户联系人或组重新阅读消息。如果没有_uniq(或类似工具),我会收到所有未读消息。请注意,我在下面添加了一个可行的解决方案,但我觉得这不是理想的方法。非常感谢,我特别尝试避免在我的第一个应用程序中使用一些便利软件包(或至少是第一次迭代)要真正深入了解Meteor并尽可能多地学习。您能否添加一个示例,说明如何更改我的发布功能以使用observeChanges
和added
?在查看了observeChanges和Meteor publish composite之后,我不确定您是否理解我提出的问题,或者我不明白您的意思你的回答是,我不想发表一篇文章,我只是在上面添加了对预期结果集的描述。找到这个讨论后,我觉得这是正确的方法。