多面向搜尋

多面向 (Facet) 搜尋可讓您將類別資訊附加至文件。Facet 是指屬性/值組合,例如名為「size」的 Facet,可能擁有「small」、「medium」及「large」等值。

使用 Facet 搭配搜尋可擷取匯總資訊,協助您透過一系列步驟修正查詢及「細查」結果。

這非常適合用於購物網站等應用,您可於其中提供一組篩選條件,協助客戶縮小範圍,找出希望瀏覽的產品。

Facet 匯總資料可顯示 Facet 值的分佈情形。舉例來說,「size」Facet 可能出現在結果集的許多文件之中。該 Facet 的匯總資料可能顯示「small」值出現 100 次、「medium」值出現 300 次,以及「large」值出現 250 次。每個 Facet/值組合都代表查詢結果之中的子集。名為「分類標籤」的鍵與各個組合有關。您可在查詢之中納入分類標籤,擷取符合查詢字串,且具有對應至一項以上分類標籤 Facet 值的文件。

您在執行搜尋時,可選擇用於收集的 Facet 以顯示於結果,或是可以啟用 Facet 探索功能,自動選擇最常出現在文件中的 Facet。

新增 Facet 至文件

請在將文件新增至索引之前,先將 Facet 新增至文件。在指定文件欄位時,請同時執行這項作業:

def add_faceted_document(index):
    document = search.Document(
        doc_id="doc1",
        fields=[search.AtomField(name="name", value="x86")],
        facets=[
            search.AtomFacet(name="type", value="computer"),
            search.NumberFacet(name="ram_size_gb", value=8),
        ],
    )

    index.put(document)

Facet 類似於文件欄位,其中具有名稱,並取用一個值。

Facet 名稱遵循與文件欄位相同的規則:名稱會區分大小寫,並且只能包含 ASCII 字元。名稱必須以字母為開頭,可包含字母、數字或底線。名稱長度不得超過 500 個字元。

Facet 值可為不可分割字串 (不得超過 500 個字元) 或數字 (介於 -2,147,483,647 及2,147,483,647 之間的雙精度浮點值)。

您可在單一文件指派多個值至單一 Facet,方法為新增相同名稱的 Facet 並輸入多次,每次使用不同的值。

Facet 可擁有無限數量的值。您可以新增至文件的 Facet 數量,或是索引之中不重複名稱 Facet 的數量,都不會受到限制。

請注意,每次使用 Facet 時,Facet 可能取得不可分割值或數值。名為「size」的 Facet,可利用「small」字串值附加至一份文件,並以數值 8 附加至另一份文件。事實上,相同的 Facet 可利用這兩種值,在同一份文件出現多次。雖然允許使用,但我們不建議針對相同的 Facet 同時使用 atom 及數值。

雖然 Facet 新增至文件時具有特定類型,但搜尋結果會將 Facet 的「所有」值收集在一起。例如,「size」Facet 可能顯示「small」值有 100 個執行個體、「medium」值有 150 個執行個體,以及範圍 [4, 8) 數值的 135 個執行個體。其中並不會顯示確切數值及其頻率分佈。

您使用查詢功能擷取文件時,無法直接存取其 Facet 與值。您必須要求查詢傳回該 Facet 資訊,作法將於下節說明。

使用多面向 (Facet) 搜尋擷取 Facet 資訊

您可要求搜尋後端探索最常用的 Facet;這稱為自動 Facet 探索。您也可以依據名稱或是名稱與值,明確地擷取 Facet 資訊。您可在單一查詢之中混搭使用所有三種 Facet 擷取。

要求 Facet 資訊不會影響查詢傳回的文件,這可能會影響效能。以預設深度 1000 執行多面向 (Facet) 搜尋,與設定排序選項計分器限制為 1000 的效果相同。

自動 Facet 探索

自動 Facet 探索會尋找文件「匯總」之中最常出現的 Facet。舉例來說,假設符合查詢的文件包含「color」Facet,以「red」值出現五次、「white」值出現五次,以及「blue」顏色出現五次。此 Facet 的總數為 15。就探索目的而言,相較於在同一個符合文件之中以「dark」值出現 6 次及以「light」值出現 7 次的 Facet「shade」,「color」Facet 的排名可能較高。

您必須在查詢之中設定,以啟用 Facet 探索功能:

def facet_discovery(index):
    # Create the query and enable facet discovery.
    query = search.Query("name:x86", enable_facet_discovery=True)
    results = index.search(query)

    for facet in results.facets:
        print("facet {}.".format(facet.name))
        for value in facet.values:
            print(
                "{}: count={}, refinement_token={}".format(
                    value.label, value.count, value.refinement_token
                )
            )

您以探索功能擷取 Facet 時,依據預設只會傳回 10 個最常產生的 Facet 值。您可以使用 FacetOptions discovery_limit 參數將這個限制放寬為 100。

請注意,自動 Facet 探索未必能傳回所有可能的 Facet 及其值。探索功能傳回的 Facet 值在每次執行之間可能不同。如果需要固定的 Facet 組合,請在查詢使用 return_facets 參數。

字串值將會個別傳回。探索 Facet 的數值將以單一範圍傳回 [最小值 最大值)。您可檢驗此項範圍,並建立更小的子範圍供後續查詢使用。

依名稱選擇 Facet

如想僅依名稱擷取 Facet 資訊,請將 return_facets 參數和清單中的 Facet 名稱新增至查詢要求:

def facet_by_name(index):
    # Create the query and specify to only return the "type" and "ram_size_gb"
    # facets.
    query = search.Query("name:x86", return_facets=["type", "ram_size_gb"])
    results = index.search(query)

    for facet in results.facets:
        print("facet {}".format(facet.name))
        for value in facet.values:
            print(
                "{}: count={}, refinement_token={}".format(
                    value.label, value.count, value.refinement_token
                )
            )

當您以名稱擷取 Facet 時,依據預設只會傳回 10 個最常產生的 Facet 值。您可以使用 FacetOptions discovery_value_limit 參數將這個限制放寬為 20 個。

依名稱與值選擇 Facet

如想僅擷取特定 Facet 值的相關資訊,請新增 return_facets 參數,當中包含具備值清單的 FacetRequest 物件:

def facet_by_name_and_value(index):
    # Create the query and specify to return the "type" facet with values
    # "computer" and "printer" and the "ram_size_gb" facet with value in the
    # ranges [0,4), [4, 8), and [8, max].
    query = search.Query(
        "name:x86",
        return_facets=[
            search.FacetRequest("type", values=["computer", "printer"]),
            search.FacetRequest(
                "ram_size_gb",
                ranges=[
                    search.FacetRange(end=4),
                    search.FacetRange(start=4, end=8),
                    search.FacetRange(start=8),
                ],
            ),
        ],
    )

    results = index.search(query)
    for facet in results.facets:
        print("facet {}".format(facet.name))
        for value in facet.values:
            print(
                "{}: count={}, refinement_token={}".format(
                    value.label, value.count, value.refinement_token
                )
            )

單一 FacetRequest 的值都必須屬於相同類型,可為字串值清單或 FacetRanges 清單 (若為數字),也就是在左側 (開始) 關閉,右側 (結束) 開啟的間隔。如果 Facet 混合字串值與數值,請針對每個類型的值新增獨立的 FacetRequests。

選項

您可以將 facet_options 參數新增至 Query 呼叫來控制多面向 (Facet) 搜尋。此參數會取用 FacetOptions 的單一例項。您可以使用此參數覆寫多面向 (Facet) 搜尋的預設行為。

options = FacetOptions(discover_facet_limit=5,
                       discover_facet_value_limit=10,
                       depth=6000);
參數 說明 預設
discover_facet_limit 在已開啟 Facet 探索的情況下,可探索的 Facet 數量。若為 0,將會停用 Facet 探索。 10
discover_facet_value_limit 針對每個已探索 Facet 數量最高的項目,可傳回的值數量。 10
depth 查詢結果中的文件數量下限,可用來評估收集 Facet 資訊。 1000

depth 選項適用於全部三種 Facet 匯總:依名稱、依名稱和值,以及自動探索。其他選項則僅適用於自動探索。

請注意,該 Facet 深度通常遠高於查詢限制。Facet 結果至少會運算至文件的深度數。如果您讓排序選項計分限制設定高於深度,就會改為使用計分限制。

擷取 Facet 結果

您在查詢中使用多面向 (Facet) 搜尋參數時,匯總 Facet 資訊會隨著查詢結果本身提供。

查詢將會有 FacetResult 清單。對於出現在符合查詢的文件中的各個 Facet,清單中各會有一個結果。您可以在各項結果中獲得下列資訊:

  • Facet 名稱
  • 最常出現的 Facet 值清單。每個值都會有一個近似計數,計算值出現的次數,並且會有一個修正鍵,可用來擷取符合這項查詢和 Facet 值的文件。

請注意,值清單包含 Facet 字串值「及」數值。若 Facet 為自動探索,其數值將以單一間隔 [最小值 最大值) 傳回。若您在查詢之中明確要求一個或多個範圍的數值 Facet,清單將包含各個範圍的關閉開啟間隔 [開始 結束)。

由於查詢選項會判斷待檢驗的文件數量及傳回的值數量,因此 Facet 值清單可能並未包含文件內找到的所有值。

您可以從搜尋結果讀取各個 Facet 的匯總資訊:

query = search.Query(...)
results = index.search(query)
for facet_info in results.facets:
  ...

例如,查詢可能已經找到文件,其中具有含字串值和數值的「size」Facet。這個 Facet 的 FacetResult 結構如下:

FacetResult(name='size', values=[
  FacetResultValue(label='[8, 10)', 22, refinement=refinement_key),
  FacetResultValue(label='small', 100, refinement=refinement_key),
  FacetResultValue(label='medium', 300, refinement=refinement_key),
  FacetResultValue(label='large', 250, refinement=refinement_key)])

label 參數是由 Facet 值所建構。對於數值,label 是範圍的表示法。

refinement_key 是可用於後續查詢的網路/網址安全字串,可擷取符合結果的 Facet 名稱和值的文件。

使用 Facet 修正/篩選查詢

與各個 FacetResultValue 相關聯的分類標籤可用來進一步縮小結果範圍,僅顯示含有這些 Facet 值的文件。如要使用一或多個這類鍵來修正查詢,請將鍵傳送至查詢物件:

query = search.Query(..., facet_refinements=[refinement_key1, refinement_key2, refinement_key3])

您可在同一個要求中,將用於一或多個不同 Facet 的分類標籤加以合併。屬於相同 Facet 的所有分類標籤會以 OR 彙整;屬於不同 Facet 的分類標籤會以 AND 合併。

您也可以手動建立自訂 FacetRefinement 鍵。詳情請參閱類別說明文件。