Menangani Hasil Penelusuran

Jika panggilan kueri selesai secara normal, panggilan akan menampilkan hasilnya sebagai objek SearchResults. Objek hasil memberi tahu Anda berapa banyak dokumen yang cocok yang ditemukan dalam indeks, dan berapa banyak dokumen yang cocok yang ditampilkan. Objek hasil juga menyertakan daftar ScoredDocuments yang cocok. Daftar tersebut biasanya berisi sebagian dari semua dokumen yang cocok yang ditemukan, karena penelusuran menampilkan sejumlah dokumen yang terbatas setiap kali dipanggil. Dengan menggunakan offset atau kursor, Anda dapat mengambil semua dokumen yang cocok, satu subset setiap kalinya.

Hasil

def query_results(index, query_string):
    result = index.search(query_string)
    total_matches = result.number_found
    list_of_docs = result.results
    number_of_docs_returned = len(list_of_docs)
    return total_matches, list_of_docs, number_of_docs_returned

Bergantung pada nilai opsi kueri limit, jumlah dokumen yang cocok yang ditampilkan dalam hasil mungkin kurang dari jumlah yang ditemukan. Ingatlah bahwa jumlah yang ditemukan akan berupa perkiraan jika jumlah yang ditemukan memiliki akurasi lebih kecil dari jumlah yang ditemukan. Terlepas dari cara Anda mengonfigurasi opsi penelusuran, panggilan search() tidak akan menemukan lebih dari 10.000 dokumen yang cocok.

Jika dokumen yang ditemukan lebih banyak daripada yang ditampilkan dan Anda ingin mengambil semuanya, Anda perlu mengulangi penelusuran menggunakan offset atau kursor, seperti yang dijelaskan di bawah ini.

Dokumen yang diberi skor

Hasil penelusuran akan menyertakan daftar ScoredDocuments yang cocok dengan kueri. Anda dapat melakukan iterasi pada daftar tersebut untuk memproses setiap dokumen satu per satu:

for scored_document in results:
        print(scored_document)

Secara default, dokumen yang diberi skor berisi semua kolom dokumen asli yang diindeks. Jika opsi kueri Anda menentukan returned_fields, hanya kolom tersebut yang akan muncul di properti fields pada dokumen. Jika Anda membuat kolom komputasi dengan menentukan returned_expressions atau snippeted_fields, kolom tersebut akan muncul secara terpisah di properti ekspresi dokumen.

Menggunakan offset

Jika penelusuran Anda menghasilkan lebih banyak dokumen daripada yang dapat dikembalikan sekaligus, gunakan offset untuk mengindeks ke dalam daftar dokumen yang cocok. Misalnya, batas kueri default adalah 20 dokumen. Setelah Anda menjalankan pencarian untuk pertama kalinya (dengan offset 0) dan mengambil 20 dokumen pertama, ambil 20 dokumen berikutnya dengan mengatur offset menjadi 20 dan jalankan kembali pencarian yang sama. Terus ulangi penelusuran, dengan menambah offset setiap kali dengan jumlah dokumen yang ditampilkan:

def query_offset(index, query_string):
    offset = 0

    while True:
        # Build the query using the current offset.
        options = search.QueryOptions(offset=offset)
        query = search.Query(query_string=query_string, options=options)

        # Get the results
        results = index.search(query)

        number_retrieved = len(results.results)
        if number_retrieved == 0:
            break

        # Add the number of documents found to the offset, so that the next
        # iteration will grab the next page of documents.
        offset += number_retrieved

        # Process the matched documents
        for document in results:
            print(document)

Offset bisa menjadi tidak efisien saat melakukan iterasi pada kumpulan hasil yang sangat besar.

Menggunakan kursor

Anda juga dapat menggunakan kursor untuk mengambil subrentang hasil. Kursor berguna ketika Anda bermaksud untuk mempresentasikan hasil penelusuran di halaman yang berurutan dan ingin memastikan Anda tidak melewatkan dokumen apa pun jika indeks dapat dimodifikasi di antara kueri. Kursor juga lebih efisien saat melakukan iterasi pada kumpulan hasil yang sangat besar.

Untuk menggunakan kursor, Anda harus membuat kursor awal dan menyertakannya dalam opsi kueri. Ada dua jenis kursor, per kueri dan per hasil. Kursor per kueri menyebabkan kursor terpisah dikaitkan dengan objek hasil yang ditampilkan oleh panggilan penelusuran. Kursor per hasil menyebabkan kursor dikaitkan dengan setiap dokumen yang diberi skor dalam hasil.

Menggunakan kursor per kueri

Secara default, kursor yang baru dibuat adalah kursor per kueri. Kursor ini menyimpan posisi dokumen terakhir yang ditampilkan di hasil penelusuran. Data ini diperbarui dengan setiap penelusuran. Untuk menghitung semua dokumen yang cocok dalam indeks, jalankan penelusuran yang sama hingga hasilnya menampilkan kursor null:

def query_cursor(index, query_string):
    cursor = search.Cursor()

    while cursor:
        # Build the query using the cursor.
        options = search.QueryOptions(cursor=cursor)
        query = search.Query(query_string=query_string, options=options)

        # Get the results and the next cursor
        results = index.search(query)
        cursor = results.cursor

        for document in results:
            print(document)

Menggunakan kursor per hasil

Untuk membuat kursor per hasil, Anda harus menetapkan properti kursor per_result ke true (benar) saat membuat kursor awal. Saat penelusuran ditampilkan, setiap dokumen akan memiliki kursor yang terkait dengannya. Anda dapat menggunakan kursor tersebut untuk menentukan penelusuran baru dengan hasil yang dimulai dengan dokumen tertentu. Perhatikan bahwa saat Anda meneruskan kursor per hasil ke penelusuran, tidak akan ada kursor per kueri yang dikaitkan dengan hasil itu sendiri; result.getCursor() akan menampilkan null sehingga Anda tidak bisa menggunakannya untuk menguji apakah Anda telah mengambil semua kecocokan.

def query_per_document_cursor(index, query_string):
    cursor = search.Cursor(per_result=True)

    # Build the query using the cursor.
    options = search.QueryOptions(cursor=cursor)
    query = search.Query(query_string=query_string, options=options)

    # Get the results.
    results = index.search(query)

    document_cursor = None
    for document in results:
        # discover some document of interest and grab its cursor, for this
        # sample we'll just use the first document.
        document_cursor = document.cursor
        break

    # Start the next search from the document of interest.
    if document_cursor is None:
        return

    options = search.QueryOptions(cursor=document_cursor)
    query = search.Query(query_string=query_string, options=options)
    results = index.search(query)

    for document in results:
        print(document)

Menyimpan dan memulihkan kursor

Kursor dapat diserialisasi sebagai string yang aman bagi web, disimpan, lalu dipulihkan untuk digunakan nanti:

def saving_and_restoring_cursor(cursor):
    # Convert the cursor to a web-safe string.
    cursor_string = cursor.web_safe_string
    # Restore the cursor from a web-safe string.
    cursor = search.Cursor(web_safe_string=cursor_string)