如何在gae,ndb中使用memcache缓存分页查询?

时间:2014-05-21 15:33:47

标签: google-app-engine memcached google-cloud-datastore app-engine-ndb

我很难搞清楚如何缓存分页查询。

我正在用ndb和gae建立一个论坛。首页是默认论坛,帖子数量有限,下一页按钮可以加载更多帖子。

使用ndb fetch_page检索此帖子,我发现用户浏览页面非常常见。因此,我没有为每个用户请求查询数据存储区,而是希望将每个页面存储在内存缓存中并让它完成工作。

我试图这样做,我只能缓存下一页,但不能缓存以前的页面。

此外,我不知道当用户创建新帖子时如何使所有缓存结果无效。

任何人都可以提供帮助吗?

修改

以下代码返回给定书签(光标的urlsafe)的任何类的10条记录。

如何考虑必须向前和向后工作,如何缓存每个页面,并且您可以使针对给定查询缓存的所有查询无效,例如当用户放置新记录时。

def return_query_page(cls, size=10, bookmark=None, is_prev=None, equality_filters=None, orders=None):
    """
    Generate a paginated result on any class
    Param cls: The ndb model class to query
    Param size: The size of the results
    Param bokkmark: The urlsafe cursor of the previous queries. First time will be None
    Param is_prev: If your requesting for a next result or the previous ones
    Param equal_filters: a dictionary of {'property': value} to apply equality filters only
    Param orders: a dictionary of {'property': '-' or ''} to order the results like .order(cls.property)
    Return: a tuple (list of results, Previous cursor bookmark, Next cursor bookmark)
    """
    if bookmark:
        cursor = ndb.Cursor(urlsafe=bookmark)
    else:
        is_prev = None
        cursor = None

    q = cls.query()
    try:
        for prop, value in equality_filters.iteritems():
            q = q.filter(cls._properties[prop] == value)

        q_forward = q.filter()
        q_reverse = q.filter()

        for prop, value in orders.iteritems():
            if value == '-':
                q_forward = q_forward.order(-cls._properties[prop])
                q_reverse = q_reverse.order(cls._properties[prop])
            else:
                q_forward = q_forward.order(cls._properties[prop])
                q_reverse = q_reverse.order(-cls._properties[prop])
    except:
        return None, None, None
    if is_prev:
        qry = q_reverse
        new_cursor = cursor.reversed() if cursor else None
    else:
        qry = q_forward
        new_cursor = cursor if cursor else None

    results, new_cursor, more = qry.fetch_page(size, start_cursor=new_cursor)
    if more and new_cursor:
        more = True
    else:
        more = False

    if is_prev:
        prev_bookmark = new_cursor.reversed().urlsafe() if more else None
        next_bookmark = bookmark
        results.reverse()
    else:
        prev_bookmark = bookmark
        next_bookmark = new_cursor.urlsafe() if more else None

    return results, prev_bookmark, next_bookmark

1 个答案:

答案 0 :(得分:3)

最好使用keys_only查询,然后对每个返回的密钥执行key.get()。

这样,memcache将用于每个帖子。

示例(假设Post是模型):

keys, cursor, more = Post.query().fetch_page(30, start_cursor=cursor, keys_only=True)
entities = ndb.get_multi(keys)