处理搜索结果

查询调用在正常完成后会以 SearchResults 对象形式返回结果。结果对象会告诉您在索引中找到了多少个匹配文档,以及返回了多少个匹配文档。该对象还包含一个匹配的 ScoredDocuments 的列表。该列表通常包含找到的所有匹配文档的一部分,因为每次调用时搜索都会返回有限数量的文档。通过使用偏移或游标,可以检索所有匹配文档,每次检索一个子集。

结果

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

根据 limit 查询选项的值,结果中返回的匹配文档数可能小于找到的数量。请注意,如果 NumberFoundAccuracy 属性的值小于找到的数量,getNumberFound 方法返回的将是估算值。无论如何配置搜索选项,search() 调用找到的匹配文档数都不会超过 10000 个。

如果找到的文档多于返回的文档,并且您想要检索所有找到的文档,则需要使用偏移或游标来重复搜索,如下所述。

得分文档

搜索结果将包含一个与查询匹配的 ScoredDocuments 列表。您可以遍历列表以依次处理每个文档:

for scored_document in results:
        print(scored_document)

默认情况下,得分文档包含编入索引的原始文档的所有字段。如果您的查询选项指定了 returned_fields,则只有这些字段会显示在文档的字段属性中。如果您通过指定 returned_expressionssnippeted_fields 来创建任何计算字段,它们将单独显示在文档的表达式属性中。

使用偏移

如果搜索找到的文档多于可以一次返回的文档,请使用偏移将其编入匹配文档列表的索引中。例如,默认查询限制为 20 个文档。首次执行搜索(offset 为 0)并检索到前 20 个文档后,在检索接下来的 20 个文档时,请将 offset 设置为 20 并再次运行相同的搜索。继续重复搜索,根据返回的文档数逐次增加偏移量:

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)

遍历大型结果集时,偏移的效率很低。

使用游标

您还可以使用游标来检索结果的子范围。如果您打算在连续页面中显示搜索结果,并且希望确保在不同查询之间索引可能会有改动的情况下不跳过任何文档,游标很有用。遍历大型结果集时,游标也更高效。

如需使用游标,必须创建一个初始游标并将其包含在查询选项中。游标有两种:per-query 和 per-result。per-query 游标生成一个将与搜索调用返回的结果对象相关的单独游标。per-result 游标生成一个将与结果中的每个得分文档相关的游标。

使用 per-query 游标

默认情况下,新构造的游标是 per-query 游标。此游标保存搜索结果中返回的最后一个文档的位置。每次搜索都会更新此游标。如需枚举索引中的所有匹配文档,请执行相同的搜索,直到结果返回空游标:

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)

使用 per-result 游标

要创建 per-result 游标,您必须在创建初始游标时将游标 per_result 属性设置为 true。当搜索返回时,每个文档都将有一个与之相关联的游标。可以使用该游标来指定新搜索的结果以特定文档开头。请注意,将 per-result 游标传递给搜索时,将不会有 per-query 游标与搜索结果本身相关;result.getCursor() 将返回 null,因此您无法使用该方法来测试是否已检索到所有匹配项。

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)

保存和恢复游标

您可以将游标序列化为一个 Web 安全字符串,然后进行保护和恢复以供日后使用:

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)