Meteor: как вернуть только одну запись для каждого значения из коллекции
В настоящее время я работаю над приложением Meteor, которое также имеет функцию чата.
Я хочу иметь список всех разговоров, которые показывают самое последнее сообщение в каждом разговоре. (Аналогично образцу основного обзора беседы )
Предположим, у меня есть коллекция сообщений с переменной conversationId. Новым сообщениям присваивается новый идентификатор conversationId, а всем ответам присваивается идентификатор conversationId первого сообщения.Чтобы получить этот обзор беседы, мой вопрос заключается в том, как вернуть из моей коллекции только самую последнюю запись для каждого conversationId?
Вот где я застрял:
Template.tabsTwo.helpers({
messages: function () {
//to retrieve all messages from the logged in user, then retrieve the conversationIDs and drop duplicates
var userMessages = Messages.find({senderId: Meteor.userId()}, {sort: {date_created: -1, subject: -1}});
var userConversationIds = userMessages.map((function(a) {
return a.conversationId;
}));
var uniqueConversationIDs = [];
$.each(userConversationIds, function(i, el){
if($.inArray(el, uniqueConversationIDs) === -1) uniqueConversationIDs.push(el);
});
return Messages.find({conversationId: {$in:uniqueConversationIDs}}, {sort: {date_created: -1}});
}
});
Это все еще возвращает мне все сообщения. Я спрашиваю себя прямо сейчас, могу ли я изменить этот запрос, чтобы заставить его работать, или мне нужно подойти к этому по-другому (например, сделать цикл и a .findOne query)?
(я перепробовал много вещей и искал ответы в документах и так далее но есть проблемы с получением этого права. Любая помощь будет очень признательна.)
1 ответ:
Ваше первоначальное решение не работает, потому что вы получаете список идентификаторов разговоров, а затем отменяете всю проделанную работу, находя все сообщения для этих разговоров.
Один из подходов состоит в том, чтобы собрать все сообщения и сгруппировать их по разговору, а затем выбрать самое последнее из них в каждой группе. Вот одно из таких решений:// Fetch this user's messages. var userMessages = Messages .find({senderId: Meteor.userId()}) .fetch(); var firstMessages = _.chain(userMessages) // Group all of the messages by conversation. .groupBy('conversationId') .map(function(messages) { // For each message in this conversation's messages, choose the // first one by date. return _.chain(messages) .sortBy(function(message) {return -message.created_at;}) .first() .value(); }).value(); return firstMessages;
firstMessages
представляет собой массив документов сообщений, содержащих первое сообщение, добавленное текущим пользователем в каждом разговоре. он / она принимал в этом участие. Вы можете просто вернуть это значение из вашего помощника, но если вы хотите вернуть курсор, просто добавьте следующее:var messageIds = _.pluck(userMessages, '_id'); return Messages.find({_id: {$in: messageIds}});