2

当我使用 RTFM 时,我无法理解如何使用手册中描述的技术指定分页搜索。这是我的代码:

def find_documents(query_string, limit, cursor):
    try:
        subject_desc = search.SortExpression(
            expression='date',
            direction=search.SortExpression.DESCENDING,
            default_value=datetime.now().date())

        # Sort up to 1000 matching results by subject in descending order
        sort = search.SortOptions(expressions=[subject_desc], limit=1000)

        # Set query options
        options = search.QueryOptions(
            limit=limit,  # the number of results to return
            cursor=cursor,
            sort_options=sort,
            #returned_fields=['author', 'subject', 'summary'],
            #snippeted_fields=['content']
         )
        query = search.Query(query_string=query_string, options=options)
        index = search.Index(name=_INDEX_NAME)
        # Execute the query
        return index.search(query)
    except search.Error:
        logging.exception('Search failed')
    return None


class MainAdvIndexedPage(SearchBaseHandler):
    """Handles search requests for comments."""

    def get(self):
        """Handles a get request with a query."""
        regionname = 'Delhi'
        region = Region.all().filter('name = ', regionname).get()
        uri = urlparse(self.request.uri)
        query = ''
        if uri.query:
            query = parse_qs(uri.query)
            query = query['query'][0]

        results = find_documents(query, 50, search.Cursor())
        next_cursor = results.cursor
        template_values = {
            'results': results,'next_cursor':next_cursor,
            'number_returned': len(results.results),
            'url': url, 'user' : users.get_current_user(), 
            'url_linktext': url_linktext, 'region' : region, 'city' : '', 'request' : self.request, 'form' : SearchForm(), 'query' : query
        }
        self.render_template('indexed.html', template_values)

上面的代码可以工作并进行搜索,但它不会对结果进行分页。我想知道手册中的以下代码:

next_cursor = results.cursor

next_cursor_urlsafe = next_cursor.web_safe_string
# save next_cursor_urlsafe
...
# restore next_cursor_urlsafe

results = find_documents(query_string, 20,
                         search.Cursor(web_safe_string=next_cursor_urlsafe))

next_cursor用来做什么的?我该如何存钱,存钱的目的是什么?我如何首先获得光标?代码是否应该看起来像这样,使用 memcache 保存恢复游标?

class MainAdvIndexedPage(SearchBaseHandler):
    """Handles search requests for comments."""

    def get(self):
        """Handles a get request with a query."""
        regionname = 'Delhi'
        region = Region.all().filter('name = ', regionname).get()
        uri = urlparse(self.request.uri)
        query = ''
        if uri.query:
            query = parse_qs(uri.query)
            query = query['query'][0]
        # restore next_cursor_urlsafe
        next_cursor_urlsafe = memcache.get('results_cursor')
        if last_cursor:
            results = find_documents(query_string, 50,
                         search.Cursor(web_safe_string=next_cursor_urlsafe))
    results = find_documents(query, 50, search.Cursor())
        next_cursor = results.cursor    
        next_cursor_urlsafe = next_cursor.web_safe_string
        # save next_cursor_urlsafe
        memcache.set('results_cursor', results.cursor)
        template_values = {
            'results': results,'next_cursor':next_cursor,
            'number_returned': len(results.results),
            'url': url, 'user' : users.get_current_user(), 
            'url_linktext': url_linktext, 'region' : region, 'city' : '', 'request' : self.request, 'form' : SearchForm(), 'query' : query
        }
        self.render_template('indexed.html', template_values)

更新

从我从答案中看到的,我应该使用 HTTP GET 查询字符串来保存光标,但我仍然不知道具体如何。请告诉我怎么做。

更新 2

这是我的新尝试。

 def get(self):
    """Handles a get request with a query."""
    regionname = 'Delhi'
    region = Region.all().filter('name = ', regionname).get()

    cursor = self.request.get("cursor")

    uri = urlparse(self.request.uri)
    query = ''
    if uri.query:
        query = parse_qs(uri.query)
        query = query['query'][0]
    logging.info('search cursor: %s', search.Cursor())

    if cursor: 
        results = find_documents(query, 50, cursor)
    else:
       results = find_documents(query, 50, search.Cursor())
    next_cursor = None
    if results and results.cursor:
        next_cursor = results.cursor.web_safe_string
    logging.info('next cursor: %s', str(next_cursor))
    template_values = {
        'results': results,'cursor':next_cursor,
        'number_returned': len(results.results),
        'user' : users.get_current_user(), 
        'region' : region, 'city' : '', 'request' : self.request, 'form' : SearchForm(), 'query' : query
    }

我认为我已经理解了它应该如何与上述内容一起工作,并且它在第一次点击时输出一个光标,所以我可以知道如何首先获得光标。这已经足够清楚地记录在案了。但我收到此错误消息:cursor must be a Cursor, got unicode

4

1 回答 1

3

不,您不应该为此使用 memcache,尤其是使用像“results_cursor”这样的常量键 - 这意味着所有用户都会获得相同的光标,这很糟糕。

您已经将光标传递给模板上下文(尽管您应该像在第二个示例中那样转换为 web_safe_string)。在模板中,您应该确保光标字符串包含在“下一步”按钮的 GET 参数中:然后,回到视图中,您应该从那里提取它并将其传递给find_documents调用。

除了 memcache 问题,第二个示例几乎已经完成,但显然您应该确保第二个调用find_documents位于else块内,这样它就不会覆盖游标版本。

于 2013-05-21T09:33:44.767 回答