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

いいえ、特に「results_cursor」のような定数キーでは、memcache を使用しないでください。これは、すべてのユーザーが同じカーソルを取得することを意味し、これは悪いことです。

すでにカーソルをテンプレート コンテキストに渡しています (ただし、2 番目の例のように web_safe_string に変換する必要があります)。テンプレートでは、カーソル文字列が「次へ」ボタンの GET パラメータに含まれていることを確認する必要があります。その後、ビューに戻り、そこからカーソル文字列を抽出してfind_documents呼び出しに渡す必要があります。

memcache の問題は別として、2 番目の例ではほぼ完了していますが、2 番目の呼び出しがブロックfind_documents内にあることを確認してelse、カーソルのバージョンを上書きしないようにする必要があります。

于 2013-05-21T09:33:44.767 に答える