多面向 (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 新增至文件。在指定文件欄位時,請同時執行這項作業:
package app
import (
"appengine"
"appengine/search"
"net/http"
)
type ComputerDoc struct {
Name search.Atom
Type search.Atom `search:",facet"`
RAMSizeGB float64 `search:",facet"`
}
func handlePut(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
index, err := search.Open("products")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
_, err = index.Put(c, "doc1", &ComputerDoc{
Name: "x86",
Type: "computer",
RAMSizeGB: 8.0,
})
// Handle err and write HTTP response.
}
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 探索功能:
func handleSearch(w http.ResponseWriter, r *http.Request) {
index, err := search.Open("products")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
it := index.Search(c, "name:x86", &search.SearchOptions{
Facets: {
search.AutoFacetDiscovery(0, 0),
},
})
facets, err := it.Facets()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
for _, results := range facets {
for i, facet := range result {
// The facet results are grouped by facet name.
// Print the name of each group before its values.
if i == 0 {
fmt.Fprintf(w, "Facet %s:\n", facet.Name)
}
fmt.Fprintf(w, " %v: count=%d", facet.Value, facet.Count)
}
}
}
您以探索功能擷取 Facet 時,依據預設只會傳回 10 個最常產生的 Facet 值。您可以使用 AutoFacetDiscovery 的第一個參數,將此限制提高至 100。
請注意,自動 Facet 探索未必能傳回所有可能的 Facet 及其值。探索功能傳回的 Facet 值在每次執行之間可能不同。如果需要固定的 Facet 組合,請在查詢使用 return_facets 參數。
字串值將會個別傳回。探索 Facet 的數值將以單一範圍傳回 [最小值 最大值)。您可檢驗此項範圍,並建立更小的子範圍供後續查詢使用。
依名稱選擇 Facet
如需僅依據名稱擷取 Facet 資訊,請將FacetDiscovery 及 Facet 名稱新增至查詢的搜尋選項:
it := index.Search(c, "name:x86", &search.SearchOptions{
Facets: {
FacetDiscovery("Type"),
FacetDiscovery("RAMSizeGB"),
},
})
您依據名稱擷取 Facet 時,只會傳回 10 個最常產生的 Facet 值。
依名稱與值選擇 Facet
如需僅擷取特定 Facet 值相關資訊,請新增 FacetDiscovery 及 Facet 名稱與需要關注的值:it := index.Search(c, "name:x86", &search.SearchOptions{
Facets: {
// Fetch the "Type" facet with Values "computer" and "printer"
FacetDiscovery("Type",
search.Atom("computer"),
search.Atom("printer"),
),
// Fetch the "RAMSizeGB" facet with values in the ranges [0, 4), [4, 8), and [8, max]
FacetDiscovery("RAMSizeGB",
search.Range{Start: 0, End: 4},
search.Range{Start: 4, End: 8},
search.AtLeast(8),
),
},
})
單一 FacetDiscovery 的值都必須屬於相同類型,可為 search.Atom 值清單或 {0}FacetRanges{/0} 清單 (若為數字),也就是在左側 (開始) 關閉,右側 (結束) 開啟的間隔。search.Range如果 Facet 混合字串值與數值,請針對每個類型的值新增獨立的 FacetDisovery 選項。
選項
您可控制收集 Facet 資訊時評估文件數量的最小值,方法為在SearchOptions 中新增 FacetDocumentDepth 選項進行查詢。如未指定,此深度預設為 1000。請注意,該 Facet 深度通常遠高於查詢限制。Facet 結果至少會運算至文件的深度數。如果您讓排序選項計分限制設定高於深度,就會改為使用計分限制。
擷取 Facet 結果
您在查詢中使用多面向 (Facet) 搜尋參數時,匯總 Facet 資訊會隨著查詢結果本身提供。
搜尋 Iterator 有 Facets 方法,可傳回匯總的切面資訊,格式為 [][]FacetResult。系統會將結果分門別類,每個 Facet 都會顯示一個切片,而這些 Facet 出現在符合查詢的文件中。您可以在各項結果中獲得下列資訊:
- Facet 名稱
- 最常見值清單中的一個 Facet 值
- 值出現次數的近似計數
請注意,值清單包含 Facet 字串值「及」數字值。若 Facet 為自動探索,其數值將以單一間隔 [最小值 最大值) 傳回。若您在查詢之中明確要求一個或多個範圍的數值 Facet,清單將包含各個範圍的關閉開啟間隔 [開始 結束)。
Facet 值清單可能並未包含在文件發現的所有值,因為查詢選項會判定要檢驗多少文件,以及傳回多少值。
各個 Facet 的匯總資訊可由疊代器讀取:
it := index.Search(...)
facets, err := it.Facets() // And check err != nil.
for _, results := range facets {
for _, facet := range results {
...
}
}
例如查詢可能發現文件,其中具有含字串值和數值的「size」Facet。此 Facet 結果的結構如下:
[][]search.FacetResult{
{
{Name: "size", Value: search.Range{Start: 8, End: 10}, Count: 22},
{Name: "size", Value: search.Atom("small"), Count: 100},
{Name: "size", Value: search.Atom("medium"), Count: 300},
{Name: "size", Value: search.Atom("large"), Count: 250},
},
}
使用 Facet 修正/篩選查詢
每個 FacetResult 可用來進一步縮小結果範圍,僅顯示含有這些 Facet 值的文件。如需以一個或多個這類鍵修正查詢,請將其傳送做為搜尋選項:
it := index.Search(c, "...", &search.SearchOptions{
Refinements: []search.Facet{
facetResult1.Facet,
facetResult2.Facet,
},
})
您可在同一個要求中,將用於一或多個不同 Facet 的分類標籤加以合併。屬於相同 Facet 的所有分類標籤會以 OR 彙整;屬於不同 Facet 的分類標籤會以 AND 合併。
您也可以手動建立自訂 Facet,做為精緻化使用。詳情請參閱參考資料。