代码之家  ›  专栏  ›  技术社区  ›  Sam

GAE-如何在没有加入的情况下生活?

  •  13
  • Sam  · 技术社区  · 17 年前

    示例问题:

    实体:

    • 用户包含姓名和好友列表(用户参考)
    • 博客帖子包含标题、内容、日期和作者(用户)

    要求:

    我想要一个页面,显示用户朋友最近10篇帖子的标题和博客链接。我还希望能够继续翻阅旧条目。

    SQL解决方案:

    因此,在sql land中,它类似于:

    select * from blog_post where user_id in (select friend_id from user_friend where user_id = :userId) order by date
    

    我能想到的GAE解决方案是:

    • 加载用户,循环浏览好友列表并加载他们的最新博客帖子。最后合并所有博客文章,找到最新的10个博客条目
    • 在博客文章中,列出所有将作者作为朋友的用户。这意味着一个简单的阅读,但当添加一个有很多博客文章的朋友时,会导致配额过载。

    我不相信这两种解决方案都会扩大规模。

    我相信其他人也遇到了这个问题,但我搜索过、看过谷歌io视频、阅读过其他人的代码。..我错过了什么?

    4 回复  |  直到 5 年前
        1
  •  13
  •   Nick Johnson    17 年前

    如果你看看你提供的SQL解决方案将如何执行,它基本上是这样的:

    1. 获取当前用户的好友列表
    2. 对于列表中的每个用户,开始对最近的帖子进行索引扫描
    3. 合并并加入步骤2中的所有扫描,当您检索到足够的条目时停止

    您可以在App Engine中自己执行完全相同的过程,将Query实例用作迭代器并对其进行合并连接。

    你说得对,这不会很好地扩展到大量的朋友,但它也存在与SQL实现完全相同的问题,它只是没有掩盖这些问题:获取最新的20个条目(例如)大约需要O(n log n)的工作,其中n是朋友的数量。

        2
  •  7
  •   Sam    16 年前

    这个话题在谷歌io演讲中有所涉及: http://code.google.com/events/io/sessions/BuildingScalableComplexApps.html

    基本上,谷歌团队建议使用列表属性和他们所谓的关系索引实体,可以在这里找到一个示例应用程序: http://pubsub-test.appspot.com/

        3
  •  1
  •   S.Lott    17 年前

    加载用户,遍历好友列表并加载他们的最新博客帖子

    这就是连接的全部——嵌套循环。某些类型的连接是带有查找的循环。大多数查找只是循环;有些是哈希值。

    “最后合并所有博客文章,找到最新的10个博客条目”

    这是一个有限制的订单。这就是数据库为你做的。

    我不确定这有什么不可扩展的;无论如何,这就是数据库所做的。

        4
  •  0
  •   amit kumar    14 年前

    以下是python中的一个示例 http://pubsub-test.appspot.com/ :

    有人用java吗?谢谢。

    from google.appengine.ext import webapp
    
    from google.appengine.ext import db
    
    class Message(db.Model):
     body = db.TextProperty(required=True)
     sender = db.StringProperty(required=True)
     receiver_id = db.ListProperty(int)
    
    class SlimMessage(db.Model):
     body = db.TextProperty(required=True)
     sender = db.StringProperty(required=True)
    
    class MessageIndex(db.Model):  
     receiver_id = db.ListProperty(int)
    
    class MainHandler(webapp.RequestHandler):
    
     def get(self):
      receiver_id = int(self.request.get('receiver_id', '1'))
      key_only = self.request.get('key_only').lower() == 'on'
      if receiver_id:
        if key_only:
          keys = db.GqlQuery(
              'SELECT __key__ FROM MessageIndex WHERE receiver_id = :1',
              receiver_id).fetch(10)
          messages.extend(db.get([k.parent() for k in keys]))
        else:
          messages.extend(Message.gql('WHERE receiver_id = :1',
                          receiver_id).fetch(10))
    
    推荐文章