I want to create a messaging app in Meteor (using the auth branch). It has a Messages collection, where each document has an array of reply documents (“replies”). In the sidebar we have different Views of the messages collection, where each view has a “query” field, which is supplied as an argument to the Meteor.publish(‘messages’)… method.
So far so good. If I click on a view, the main part of the page displays a list of messages which match the query. For each message, I show it in bold if there are any replies that are newer than the last time the current user opened the message, or if she has never opened the message. I do this by maintaining a “read_by” field for each message, which contains an array of {user_id, …, read_at: …} records. This works beautifully too.
The problem is that I need each view in the sidebar to show a badge with the number of unread messages (as per the logic in the previous paragraph) for each view, not just the currently selected one.
How can I solve this? As far as I can tell, it means that I need to maintain a number of live queries against the Messages collection. At the same time, it is not an option for the client to subscribe to the entire Messages collection – let’s assume that it holds millions of documents. The client must remain snappy no matter how many documents are in the DB collection on the server.
I suspect that this requires a different schema design (which is not a problem), but I can’t quite see it.
I think you have two options.
The easier option (which is perhaps not the most efficient) is to subscribe to all the different queries you are interested in:
And when you need the messages, use the same query to select only the ones you are interested in:
Obviously, you can then do the counts you need.
The other alternative would be to publish a special counts collection, which is manually setup. First, do something very similar to the
counts-by-roomexample in the publishing section of the docs, then client side, do something like:Each subscription to
counts-by-querywill maintain one record in the counts collection.Hope that helps!