如何在Google App Engine上设计线程样式的消息传递系统

时间:2011-08-26 16:00:07

标签: google-app-engine django-nonrel

我正在尝试使用Django-nonrel在Google App Engine上设计类似线程消息系统的gmail。我看过“在App Engine上构建可扩展的复杂应用程序”,并在SO上阅读以下问题。

App Engine Messaging System with Message Status - Design Pattern
database design in google app engine

我喜欢Kevin指出的想法(App Engine Messaging System with Message Status - Design Pattern),所以我现在的模型是这样的:

class Message(models.Model):
    sender = models.ForeignKey(User)
    content = models.TextField()
    thread_id = models.IntegerField()

class MessageReceivers(models.Model):
    message = models.ForeignKey(Message)
    users = ListField(models.CharField())
    status = models.IntegerField()  # 1 unread, 2 read ....

Django-nonrel上的ListField来自这里:
http://www.allbuttonspressed.com/blog/django/2010/03/Updates-on-djangoappengine

这是我的问题,我不知道如何实现在每个线程中显示消息计数,如gmail。让我澄清我的观点。
当用户Sirius向Harry和Ron发送消息时。模型(简化说明)应该是这样的:

Message
id = 1
sender = Sirius
thread_id = 1

MessageReceivers
message = 1
users = [Harry, Ron]

然后,哈利回复天狼星,但出于某种原因,他不包括罗恩:

Message
id = 2
sender = Harry
thread_id = 1

MessageReceivers
message = 2
users = [Sirius]

小天狼星也回复哈利,但他再次包括罗恩:

Message
id = 3
sender = Sirius
thread_id = 1

MessageReceivers
message = 3
users = [Haary, Ron]

当Sirius和Harry看到他们的收件箱时,会有一个带有消息计数的帖子(3)。 Ron看到他的收件箱中有一个带有消息计数的线程(2)。我该如何计算这些数字?我应该制作一个新模型来保留它们吗?

提前致谢,

修改
当Kevin向我介绍一个Thread模型时,我意识到我不需要关系索引模型来满足我的要求,所以我现在的模型如下所示。

class Message(models.Model):
    sender = models.ForeignKey(User)
    content = models.TextField()

class Thread(models.Model):
    user = models.ForeignKey(User)
    messages = ListField(models.CharField())    # array of message id
    lastmodified = models.DateTimeField()
    # could have a status field for read or unread, not sure for now

我可能会在进一步开发中发现这些模型有困难,但我会暂时跟它们一起使用:)。

2 个答案:

答案 0 :(得分:1)

试试这个:

from collections import defaultdict

messages = MessageReceivers.objects.filter(users='Harry')

message_threads = []
for m in messages:
  message_threads.append(m.message.thread_id)

counted_threads = defaultdict(int)

for curr in message_threads:
    counted_threads[curr] += 1

这将为您提供thread_id的字典及其出现频率。

例如:

message_threads = ['a','b','c','a','a','b','a']

将产生

counts_threads == defaultdict(,{'a':4,'c':1,'b':2})

答案 1 :(得分:1)

如果您的号码太低,我只会在客户端上计算它们并忘记在服务器上计算。下载Harry的消息并计算它们。为Sirius做同样的事。你必须每次都计算它们(效率较低),但是你不必存储或维护计数(效率更高),客户端的处理时间比服务器的便宜。

这似乎特别正确,因为这个数字只是一种便利。如果你想添加一个功能,比如“根据他们的回复数量排序对话”,你需要在服务器上存储这些数量,否则你并不真正关心这个数字。