2015-11-25 7 views
2

В настоящее время я работаю над приложением Meteor, которое также имеет функцию чата.Meteor: Как вернуть только одну запись для каждого значения из коллекции

Я хочу иметь список всех разговоров, которые показывают самое последнее сообщение в каждом разговоре. (Подобный Sample of a basic conversation overview)

Скажем, у меня есть коллекция сообщения с переменной conversationId. В новых сообщениях назначается новый параметр talkId, и для любых ответов будет назначено messageId первого сообщения.

Чтобы получить обзор этой беседы, мой вопрос: как мне вернуть из моей коллекции только самую последнюю запись для каждого диалога?

Это где я застрял:

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}}); 
    } 
}); 

Это все еще дает мне все сообщения. Я задаю себе вопрос, могу ли я изменить этот запрос, чтобы он работал, или мне нужно подойти к нему по-другому (например, выполнить цикл и запрос .findOne)?

(я пробовал много вещей, и искал ответы в документации и SO, но есть проблемы получать это право. Любая помощь будет принята с благодарностью.)

+1

Поскольку это должно работать на стороне клиента, я считаю, что вы должны либо добавить' isLatest' поле для сообщения и обновлять его каждый раз, когда сообщение отправляется или выполняется цикл 'findOne'. Это минимально. Вы можете сделать это как двухэтапный процесс повышения эффективности (помощник в помощнике), что уменьшит стоимость повторного расчета. – MasterAM

ответ

0

Ваше первоначальное решение не работает, потому что вы получаете список идентификаторов беседы, а затем уничтожить всю работу, которую вы сделали, найдя все сообщения сообщений для этих разговоров.

Одним из подходов является получение всех сообщений и группировка их по цепочке, а затем выбор самой последней в каждой группе. Вот один из таких решений:.

// 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 является массивом документов сообщений, содержащих первое сообщение добавляемого текущим пользователя в каждом разговоре он/она участвовала в Вы можете просто вернуть это значение из вашего помощника, но если вы «d предпочитают возвращать курсор, просто добавьте следующее:

var messageIds = _.pluck(userMessages, '_id'); 
return Messages.find({_id: {$in: messageIds}}); 

 Смежные вопросы

  • Нет связанных вопросов^_^