Search code examples
realmrealm-listrealm-java

Realm Java Sort By RealmList Link


If I have the following models:

class Conversation extends RealmObject {
    RealmList<Message> messages;
}

class Message extends RealmObject {
    long timestamp;
}

How can I say: give me all Conversations with the list of Message sorted, and the Conversations are sorted by the top item in messages?


Solution

  • I don't know, how achieve required result in your database scheme and without join operations (not supported yet1).

    But it can be achieved, if your database scheme will be migrated to this model:

    class Conversation extends RealmObject {
        @PrimaryKey
        long id;
    
        public Long getId() {
            return id;
        }
    }
    
    class Message extends RealmObject {
        long timestamp;
        long conversationId;
    
        public long getConversationId() {
            return conversationId;
        }
    }
    

    Take note: using suggested models you need manually check for references consistency of "message -> conversation" relation.

    Next, you can take required result by code below:

    SortedSet<Message> sortedMessagesSet = new TreeSet<>(new Comparator<Message>() {
        @Override
        public int compare(Message message1, Message message2) {
            return (int) (message2.timestamp - message1.timestamp);
        }
    });
    
    List<Conversation> emptyConversations = new ArrayList<>();
    // take "top" messages of each conversation
    for (Conversation conversation : realm.where(Conversation.class).findAll()) {
        RealmResults<Message> sortedMessages = realm.where(Message.class).
                    equalTo("conversationId", conversation.getId()).
                    findAllSorted("timestamp", Sort.DESCENDING);
        // append latest (by time) message to the sorted messages set
        if (!sortedMessages.isEmpty()) sortedMessagesSet.add(sortedMessages.first());
        // remember conversations without messages
        else emptyConversations.add(conversation);
    }
    
    List<Conversation> sortedConversations = new ArrayList<>(sortedMessagesSet.size() + emptyConversations.size());
    // take conversations sorted by messages
    for (Message message : sortedMessagesSet)
            sortedConversations.add(realm.where(Conversation.class).
                    equalTo("id", message.getConversationId()).findFirst());
    
    // append empty conversations to the end
    sortedConversations.addAll(emptyConversations);
    

    1. Current version of realm is 2.3.0