解析服务器:如何使这个查询高效?

Dav*_*iha 7 parse-platform parse-server

我有一个Message类 - 它包含一个群发消息,可以按需提供给许多用户,但每个用户只需要一次,当他需要新消息时.我怎样才能确保用户在交付后再也不会再次获取它?


IDEA#1: Message.deliveredTo将是一个Relation_User物体.在Message交付给用户之后,他将自己添加到了Message.deliveredTo Relation.

当用户以后寻找未送达时Messages,他会找到Messages除了他所在的所有人之外的所有人deliveredTo Relation:

var messagesQuery = new Parse.Query("Message");
messagesQuery.notEqualTo("deliveredTo", request.user);
messagesQuery.find() ...
Run Code Online (Sandbox Code Playgroud)

IDEA#2: <messageId>_delivered是在Role创建Messageid时<messageId>创建的.该MessageACL-read是残疾人Role.在Message交付给用户之后,他将自己添加到了<messageId>_delivered Role.

当用户以后寻找未送达时Messages,他会找到Messages除了他所在的所有人之外的所有人<messageId>_delivered Role:

var messagesQuery = new Parse.Query("Message");
messagesQuery.find({ sessionToken: request.user.getSessionToken() }) ...
Run Code Online (Sandbox Code Playgroud)

IDEA#3: DeliveredMessage是一个班级.在将a Message传递给用户之后,他DeliveredMessage使用包含用户messageMessagedeliveredTo键的字段创建new .

当用户以后寻找未送达时Messages,他会找到Messages除他DeliveredMessage对象中的所有内容之外的所有内容:

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() ...
Run Code Online (Sandbox Code Playgroud)

问题是,所有选项看起来都非常低效且不符合索引.有些人比其他人好吗?为什么?

或者你有任何其他有效的想法如何实现这一点?

注意: 每个人的收件人都会Message随着时间的推移而改变(跟随者模型),因此无法添加pendingRecipients Relation字段Message,在收到用户时将其删除Message,equalTo而不是notEqualTo在检查未传递的邮件时使用.

Ale*_*lex 1

老实说,谈论效率和索引,典型查询是关键。假设从最多查询到最少查询的最高查询是:

  • 获取用户(收件人)未送达的消息数
  • 获取用户(收件人)的几个最新/最旧的消息 ID/标题的列表
  • 通过messageID获取消息内容
  • 放置消息内容和收件人

s类UndeliveredMessage将是最有效的。它至少应该有一个messageID 和一个userID。根据使用情况,您可能需要添加消息的日期、标题等。通过用户 ID 索引,您可以检索未发送消息的数量,而无需访问磁盘。

它与IDEA #3类似,有 2 个好处:

  • 将未发送消息的计算从find查询转移到创建消息或建立新的关注关系时的点。表的填充可以在后台完成,这将导致“传递”消息的延迟增加,但保持快速的操作请求。
  • 集合的大小不会随着时间的推移呈指数级增长,因为您不需要保留所有已传递的消息。