Reputation: 1436
I have a Message
class - it contains a mass message, that can be delivered on-demand to many users, but each user can get it only once, when he demands new messages. How can I ensure that user never gets it again after it has once been delivered?
IDEA #1:
Message.deliveredTo
would be a Relation
to _User
objects.
After a Message
is delivered to user, he adds himself to Message.deliveredTo
Relation
.
When user later looks for undelivered Messages
, he will find all Messages
except those that he is in deliveredTo
Relation
:
var messagesQuery = new Parse.Query("Message");
messagesQuery.notEqualTo("deliveredTo", request.user);
messagesQuery.find() ...
IDEA #2:
<messageId>_delivered
is a Role
that is created when Message
with id <messageId>
is created. The Message
's ACL-read
is disabled for the Role
.
After the Message
is delivered to user, he adds himself to <messageId>_delivered
Role
.
When user later looks for undelivered Messages
, he will find all Messages
except those that he is in <messageId>_delivered
Role
:
var messagesQuery = new Parse.Query("Message");
messagesQuery.find({ sessionToken: request.user.getSessionToken() }) ...
IDEA #3:
DeliveredMessage
is a class. After a Message
is delivered to user, he creates new DeliveredMessage
with message
field containing the Message
and deliveredTo
key containing the user.
When user later looks for undelivered Messages
, he will find all Messages
except those that are in his DeliveredMessage
objects:
var messagesQuery = new Parse.Query("Message");
var deliveredQuery = new Parse.Query("DeliveredMessage");
deliveredQuery.equalTo("deliveredTo", request.user);
messagesQuery.doesNotMatchKeyInQuery("objectId", "message.objectId" /*is that even possible?*/, deliveredQuery)
messagesQuery.find() ...
The problem is, that all the options seems very inefficient and not index-friendly. Is some of them better then the others? Why?
Or do you have any other efficient idea how to implement this?
NOTE:
Recipients of every Message
can change over time (follower model), so it is not possible to add a pendingRecipients
Relation
field to Message
, remove user from it when he receives the Message
and use equalTo
instead of notEqualTo
when checking for undelivered messages.
Upvotes: 7
Views: 249
Reputation: 37048
Honestly, talking about efficiency and indexing, typical queries is a key. With assumption that the top queries from most queried to least queried are:
A class of UndeliveredMessage
s will be most efficient. It should have at least a messageID and a userID. Depending on use-cases, you may want to add date of the message, may be title, etc. Indexing by userID you can retrieve number of undelivered messages without hitting a the disk.
It is similar to IDEA #3, with 2 benefits:
find
query to the point when message is created, or a new follow relationship established. Population of the table can be done in background, which will result with increased latency of "delivering" messages, but keep operational requests quick.Upvotes: 1