Google 開發人員關係
簡介
本課程將教導您如何按您想要的順序排序查詢搜尋的結果。
- 您可依欄位值或包含欄位值的運算式排序。
- 您可依文件頻率排名分數排序,也可以在更複雜的排名運算式中使用該分數。
- 排序可以多維方式進行,主要先依一個欄位運算式排序,然後再依另一個欄位運算式排序,依此類推。
本應用程式範例可讓使用者依關聯性結果排序,或對文件欄位執行二維排序功能。
課程目標
瞭解如何排序 Search API 搜尋查詢的結果。
事前準備
學習本課程之前必須先瞭解 Python Search API 入門指南
我們也建議您採取下列措施:
- 瞭解 Python 2.7 和 Python 專用的 Google App Engine SDK
- 熟悉 Python 與 App Engine 應用程式的基本概念
SortOptions
類別
SortOptions 類別提供定義查詢結果排序順序的基本概念。定義之後,SortOptions
object
會做為 QueryOptions
物件的 sort_options
參數使用:
from google.appengine.api import search
search.QueryOptions(
sort_options=search.SortOptions(...)
...)
排序運算式
您可將 expressions
引數傳送給 SortOptions
建構函式,該引數是可疊代的 SortExpression
物件。這樣可以讓您根據文件欄位值執行多維排序作業。
在應用程式範例的 docs.Product
類別中,您會看見類似以下的清單:
_SORT_OPTIONS = [
[AVG_RATING, 'average rating', search.SortExpression(
expression=AVG_RATING,
direction=search.SortExpression.DESCENDING, default_value=0)],
[PRICE, 'price', search.SortExpression(
expression=PRICE,
direction=search.SortExpression.ASCENDING, default_value=9999)],
[UPDATED, 'modified', search.SortExpression(
expression=UPDATED,
direction=search.SortExpression.DESCENDING, default_value=1)],
[CATEGORY, 'category', search.SortExpression(
expression=CATEGORY,
direction=search.SortExpression.ASCENDING, default_value='')],
[PRODUCT_NAME, 'product name', search.SortExpression(
expression=PRODUCT_NAME,
direction=search.SortExpression.ASCENDING, default_value='zzz')]
]
這為商品文件欄位的子集定義了 SortExpression
物件。在每個定義中,expression
參數都只是欄位名稱而已。稍後您將會看見其他運算式變因。請注意,每個排序運算式都定義了排序方向 (ASCENDING
或 DESCENDING
) 及預設值,會在文件的運算式中不包含特定欄位時使用。
在 handlers.py
中,ProductSearchHandler.doProductSearch()
方法使用這些定義內容來定義二維排序方式,方法是先定義 SortExpression
物件的排序清單,然後將此清單做為 SortOptions
建構函式的 expressions
參數傳送。如果使用者要求按平均評分排序,請依價格進行第二次排序:
sortopts = search.SortOptions(expressions=[
search.SortExpression(expression=docs.Product.AVG_RATING, direction='DESCENDING', default_value=0),
search.SortExpression(expression=docs.Product.PRICE, direction='ASCENDING', default_value=9999)])
否則 (假設使用者要求依價格排序),第二次排序將會依平均評分排序:
sortopts = search.SortOptions(expressions=[
search.SortExpression(expression=docs.Product.PRICE, direction='ASCENDING', default_value=9999),
search.SortExpression(expression=docs.Product.AVG_RATING, direction='DESCENDING', default_value=0)])
然後,像之前一樣,將此物件傳送給 QueryOptions
建構函式:
search.QueryOptions(
sort_options=sortopts
...)
在排序運算式中使用運算式函式
expression
物件中的 SortExpression
屬性可以不僅僅只是一個欄位名稱而已:您也可以像上一個課程中所提到的一樣,使用運算式函式 (例如 max
)。舉例來說,以下排序運算式就依 price
欄位值排序,並在調整後包含營業稅:
search.SortExpression(
expression='price * 1.08',
direction=search.SortExpression.ASCENDING, default_value=9999)]
依距離排序 GeoPoint 欄位
您可以尋找特定距離之內的所有商店,但是如果能依商店距離來排序商店就更好了。使用內建 distance
函式新增排序運算式就能達到此目的。以下查詢會尋找距使用者位置 4.5 公里以內的所有商店,並按遞增距離,從最近到最遠排序商店:
index = search.Index(config.STORE_INDEX_NAME)
user_location = (-33.857, 151.215)
query = "distance(store_location, geopoint(%f, %f)) < %f" % (
user_location[0], user_location[1], 45000)
loc_expr = "distance(store_location, geopoint(%f, %f))" % (
user_location[0], user_location[1])
sortexpr = search.SortExpression(
expression=loc_expr,
direction=search.SortExpression.ASCENDING, default_value=45001)
search_query = search.Query(
query_string=query,
options=search.QueryOptions(
sort_options=search.SortOptions(expressions=[sortexpr])))
results = index.search(search_query)
比對計分
MatchScorer
類別可用來依遞增順序排序文件,此類別使用的是以字詞頻率為基礎的分數。MatchScorer
物件會做為 SortOptions
建構函式的 match_scorer
參數傳送:
sortopts = search.SortOptions(match_scorer=search.MatchScorer())
search.QueryOptions(
sort_options=sortopts
...)
應用程式範例會在使用者從 UI 的查詢排序選單中選取 [relevance] 時使用此排序方式。
您也可以使用特殊欄位名稱 _score
,存取排序運算式中的文件分數。在本例中,您的 SortOptions
物件應包含計分方式,例如:
search.SortOptions(match_scorer=search.MatchScorer(),
expressions=[search.SortExpression(...),...])
摘要與回顧
您在本課程中瞭解了如何為我們的搜尋結果定義多維排序方式,方法是指定 SortExpression
與 MatchScorer
物件,並使用這些物件來建構傳送給 QueryOptions
建構函式的 SortOptions
物件。
請對排序運算式多做一點實驗,確認您瞭解排序運算式的使用方式。例如,請試著對不同的維度執行第二次排序,藉以變更 ProductSearchHandler.doProductSearch()
中的 SortOptions
物件所定義的排序維度。您也可以嘗試變更其中一個排序維度的排序方向。
在下一個課程中,您將會瞭解如何擷取、刪除 Search API 文件,以及如何將這些文件重新編入索引。