共用方式為


Azure AI 搜尋服務中的「簡單」搜尋查詢範例

在 Azure AI 搜尋服務中,簡單查詢語法會叫用預設查詢剖析器進行全文檢索搜尋。 剖析器速度快,可處理常見案例,包括全文檢索搜尋、篩選搜尋、多面向搜尋和前置詞搜尋。 本文使用範例來說明搜尋文件 (REST API) 要求中的簡單語法使用方式。

注意

替代的查詢語法是完整 Lucene,可支援如模糊和萬用字元搜尋等較複雜的查詢結構。 如需詳細資訊和範例,請參閱使用完整的 Lucene 語法

飯店範例索引

下列查詢是以 hotels-sample-index 為基礎,您可以遵循本快速入門中的指示來建立。

範例查詢會使用 REST API 和 POST 要求來表達。 您可以在 REST 用戶端貼上並加以執行。 在 Azure 入口網站中使用搜尋總管的 JSON 檢視。 在 JSON 檢視中,您可以貼上本文此處所示的查詢範例。

要求標頭必須具有下列值:

機碼
內容-類型 application/json
api-key <your-search-service-api-key> (查詢或系統管理金鑰)

URI 參數必須包含具有索引名稱、文件集合、搜尋命令和 API 版本的搜尋服務端點,類似於下列範例:

https://{{service-name}}.search.windows.net/indexes/hotels-sample-index/docs/search?api-version=2024-07-01

要求本文應格式化為有效的 JSON:

{
    "search": "*",
    "queryType": "simple",
    "select": "HotelId, HotelName, Category, Tags, Description",
    "count": true
}
  • 設定為 * 的「search」是未指定的查詢,相當於 Null 或空白搜尋。 這並不特別有用,但這是您可以執行的最簡單搜尋,而且其會顯示索引中所有可擷取的欄位,以及所有值。

  • 「queryType」設定為「simple」是預設值,可以省略,但包含它是為了進一步強調本文中的查詢範例是用簡單語法表示的。

  • 設定為以逗號分隔的欄位清單的「select」用於搜尋結果組合,只包含搜尋結果內容中有用的欄位。

  • 「count」會傳回符合搜尋準則的文件數目。 在空的搜尋字串上,此計數將會是索引中的所有文件 (在 hotels-sample-index 中,計數為 50)。

全文檢索搜尋可以是任意數目的獨立字詞或引號括起來的片語,包含或不包含布林運算子。

POST /indexes/hotel-samples-index/docs/search?api-version=2024-07-01
{
    "search": "pool spa +airport",
    "searchMode": "any",
    "queryType": "simple",
    "select": "HotelId, HotelName, Category, Description",
    "count": true
}

由重要字詞或片語組成的關鍵字搜尋通常是最適合的。 字串欄位會在編製索引和查詢、卸除非必要字組 (例如「the」、「and」、「it」) 期間進行文字分析。 若要查看查詢字串如何在索引中標記化,請在 Analyze Text 呼叫中,將字串傳遞至索引。

「searchMode」參數可控制精確度和重新叫用。 如果您想要更多重新叫用,請使用預設的「any」值,這樣如果符合查詢字串的任何部分,就會傳回結果。 如果您偏好精確度,必須比對字串的所有部分,請將 searchMode 變更為「all」。 請嘗試上述兩種查詢方式,以查看 searchMode 如何變更結果。

「pool spa +airport」查詢的回應看起來應該類似下列範例,為了簡潔起見,我們進行刪減。

"@odata.count": 6,
"value": [
    {
        "@search.score": 7.3617697,
        "HotelId": "21",
        "HotelName": "Nova Hotel & Spa",
        "Description": "1 Mile from the airport.  Free WiFi, Outdoor Pool, Complimentary Airport Shuttle, 6 miles from the beach & 10 miles from downtown.",
        "Category": "Resort and Spa",
        "Tags": [
            "pool",
            "continental breakfast",
            "free parking"
        ]
    },
    {
        "@search.score": 2.5560288,
        "HotelId": "25",
        "HotelName": "Scottish Inn",
        "Description": "Newly Redesigned Rooms & airport shuttle.  Minutes from the airport, enjoy lakeside amenities, a resort-style pool & stylish new guestrooms with Internet TVs.",
        "Category": "Luxury",
        "Tags": [
            "24-hour front desk service",
            "continental breakfast",
            "free wifi"
        ]
    },
    {
        "@search.score": 2.2988036,
        "HotelId": "35",
        "HotelName": "Suites At Bellevue Square",
        "Description": "Luxury at the mall.  Located across the street from the Light Rail to downtown.  Free shuttle to the mall and airport.",
        "Category": "Resort and Spa",
        "Tags": [
            "continental breakfast",
            "air conditioning",
            "24-hour front desk service"
        ]
    }
]

請注意回應中的搜尋分數。 這是相符項目的相關性分數。 根據預設,搜尋服務會根據此分數傳回前 50 個相符項目。

沒有排名時,分數一律為「1.0」,這是因為搜尋不是全文檢索搜尋,或是未提供任何準則。 例如,在空白搜尋 (search= *) 中,資料列會依任意順序返回。 當您包含實際準則時,您會發現搜尋分數逐漸具有其實質意義。

範例 2︰依識別碼查閱

當在查詢中傳回搜尋結果時,合乎邏輯的下一步是提供一個詳細資料頁面,其中包含來自文件的更多欄位。 此範例示範如何使用查閱文件,透過傳入文件識別碼來傳回單一文件。

GET /indexes/hotels-sample-index/docs/41?api-version=2024-07-01

所有文件都有唯一識別碼。 如果您使用入口網站,請從 [索引] 索引標籤中選取索引,然後查看欄位定義以判斷哪個欄位是索引鍵。 使用 REST,Get Index 呼叫會傳回回應本文中的索引定義。

上述查詢的回應是由索引鍵為 41 的文件所組成。 在索引定義中標示為「可擷取」的任何欄位都可以在搜尋結果中傳回,並在您的應用程式中轉譯。

{
    "HotelId": "41",
    "HotelName": "Ocean Air Motel",
    "Description": "Oceanfront hotel overlooking the beach features rooms with a private balcony and 2 indoor and outdoor pools. Various shops and art entertainment are on the boardwalk, just steps away.",
    "Description_fr": "L'hôtel front de mer surplombant la plage dispose de chambres avec balcon privé et 2 piscines intérieures et extérieures. Divers commerces et animations artistiques sont sur la promenade, à quelques pas.",
    "Category": "Budget",
    "Tags": [
        "pool",
        "air conditioning",
        "bar"
    ],
    "ParkingIncluded": true,
    "LastRenovationDate": "1951-05-10T00:00:00Z",
    "Rating": 3.5,
    "Location": {
        "type": "Point",
        "coordinates": [
            -157.846817,
            21.295841
        ],
        "crs": {
            "type": "name",
            "properties": {
                "name": "EPSG:4326"
            }
        }
    },
    "Address": {
        "StreetAddress": "1450 Ala Moana Blvd 2238 Ala Moana Ctr",
        "City": "Honolulu",
        "StateProvince": "HI",
        "PostalCode": "96814",
        "Country": "USA"
    }
}

範例 3:篩選文字

篩選語法是您可搭配 search 使用或單獨使用的 OData 運算式。 搭配使用時,會先將 filter 套用到整個索引,再對篩選結果執行搜尋。 由於篩選能夠減少搜尋查詢需要處理的資料集合,因此對於提升查詢效能方面是很實用的技術。

您可以在索引定義中標示為 filterable 的任何欄位上定義篩選條件。 對於 hotels-sample-index,可篩選的欄位包括 Category、Tags、ParkingIncluded、Rating 和大部分的 Address 欄位。

POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
    "search": "art tours",
    "queryType": "simple",
    "filter": "Category eq 'Resort and Spa'",
    "searchFields": "HotelName,Description,Category",
    "select": "HotelId,HotelName,Description,Category",
    "count": true
}

上述查詢的回應範圍僅限於分類為「Report and Spa」的旅館,其中包含「art」或「tours」等詞彙。 在此情況下,只有一個相符項目。

{
    "@search.score": 2.8576312,
    "HotelId": "31",
    "HotelName": "Santa Fe Stay",
    "Description": "Nestled on six beautifully landscaped acres, located 2 blocks from the Plaza. Unwind at the spa and indulge in art tours on site.",
    "Category": "Resort and Spa"
}

範例 4:篩選函式

篩選條件運算式可以包含 「search.ismatch」和「search.ismatchscoring」函式,讓您在篩選條件內建置搜尋查詢。 此篩選條件運算式會針對 free 使用萬用字元來選取便利設施,包含免費 wifi、免費停車等。

POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
  {
    "search": "",
    "filter": "search.ismatch('free*', 'Tags', 'full', 'any')",
    "select": "HotelId, HotelName, Category, Description",
    "count": true
  }

上述查詢的回應會比對 19 家提供免費便利設施的旅館。 請注意,搜尋分數在整個結果中都是統一的「1.0」。 這是因為搜尋運算式為 Null 或空白,導致逐字篩選條件相符,但全文檢索搜尋則否。 相關性分數只會在全文檢索搜尋時傳回。 如果您使用沒有 search 的篩選條件,請確定您有足夠的可排序欄位,以便控制搜尋排名。

"@odata.count": 19,
"value": [
    {
        "@search.score": 1.0,
        "HotelId": "31",
        "HotelName": "Santa Fe Stay",
        "Tags": [
            "view",
            "restaurant",
            "free parking"
        ]
    },
    {
        "@search.score": 1.0,
        "HotelId": "27",
        "HotelName": "Super Deluxe Inn & Suites",
        "Tags": [
            "bar",
            "free wifi"
        ]
    },
    {
        "@search.score": 1.0,
        "HotelId": "39",
        "HotelName": "Whitefish Lodge & Suites",
        "Tags": [
            "continental breakfast",
            "free parking",
            "free wifi"
        ]
    },
    {
        "@search.score": 1.0,
        "HotelId": "11",
        "HotelName": "Regal Orb Resort & Spa",
        "Tags": [
            "free wifi",
            "restaurant",
            "24-hour front desk service"
        ]
    },

範例 5︰範圍篩選條件

範圍篩選是透過適用於任何資料類型的篩選條件運算式來支援。 下列範例說明數值和字串範圍。 資料類型在範圍篩選條件中很重要,而當數值資料位於數值欄位且字串資料位於字串欄位時效果最好。 字串欄位中的數值資料不適合用於範圍,因為數值字串無法比較。

下列查詢是數值範圍。 在 hotels-sample-index 中,唯一可篩選的數值欄位是 Rating。

POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
    "search": "*",
    "filter": "Rating ge 2 and Rating lt 4",
    "select": "HotelId, HotelName, Rating",
    "orderby": "Rating desc",
    "count": true
}

查詢的回應看起來應該類似下列範例,為了簡潔起見,我們進行刪減。

"@odata.count": 27,
"value": [
    {
        "@search.score": 1.0,
        "HotelId": "22",
        "HotelName": "Stone Lion Inn",
        "Rating": 3.9
    },
    {
        "@search.score": 1.0,
        "HotelId": "25",
        "HotelName": "Scottish Inn",
        "Rating": 3.8
    },
    {
        "@search.score": 1.0,
        "HotelId": "2",
        "HotelName": "Twin Dome Motel",
        "Rating": 3.6
    }
...

下一個查詢是字串欄位 (Address/StateProvince) 的範圍篩選條件:

POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
    "search": "*",
    "filter": "Address/StateProvince ge 'A*' and Address/StateProvince lt 'D*'",
    "select": "HotelId, HotelName, Address/StateProvince",
    "count": true
}

查詢的回應看起來應該類似下列範例,為了簡潔起見進行了刪減。 在此範例中,無法依 StateProvince 排序,因為欄位不會在索引定義中屬性化為「可排序」。

"@odata.count": 9,
"value": [
    {
        "@search.score": 1.0,
        "HotelId": "9",
        "HotelName": "Smile Hotel",
        "Address": {
            "StateProvince": "CA "
        }
    },
    {
        "@search.score": 1.0,
        "HotelId": "39",
        "HotelName": "Whitefish Lodge & Suites",
        "Address": {
            "StateProvince": "CO"
        }
    },
    {
        "@search.score": 1.0,
        "HotelId": "7",
        "HotelName": "Countryside Resort",
        "Address": {
            "StateProvince": "CA "
        }
    },
...

hotels-sample 索引包含具有經度和緯度座標的 Location 欄位。 這個範例會使用 geo.distance 函式,以篩選起始點周圍以至您提供的任意距離 (以公里為單位) 內的文件。 您可以調整查詢 (10) 中的最後一個值,以縮小或放大查詢的介面區。

POST /indexes/v/docs/search?api-version=2024-07-01
{
    "search": "*",
    "filter": "geo.distance(Location, geography'POINT(-122.335114 47.612839)') le 10",
    "select": "HotelId, HotelName, Address/City, Address/StateProvince",
    "count": true
}

此查詢的回應會傳回距離所提供座標 10 公里內的所有旅館:

{
    "@odata.count": 3,
    "value": [
        {
            "@search.score": 1.0,
            "HotelId": "45",
            "HotelName": "Arcadia Resort & Restaurant",
            "Address": {
                "City": "Seattle",
                "StateProvince": "WA"
            }
        },
        {
            "@search.score": 1.0,
            "HotelId": "24",
            "HotelName": "Gacc Capital",
            "Address": {
                "City": "Seattle",
                "StateProvince": "WA"
            }
        },
        {
            "@search.score": 1.0,
            "HotelId": "16",
            "HotelName": "Double Sanctuary Resort",
            "Address": {
                "City": "Seattle",
                "StateProvince": "WA"
            }
        }
    ]
}

範例 7︰使用 searchMode 的布林值

簡單語法支援字元形式的布林運算子 (+, -, |),以支援 AND、OR 和 NOT 查詢邏輯。 布林搜尋的行為會如預期般運作,但有一些值得注意的例外狀況。

在先前的範例中,searchMode 參數已引進為影響精確度和重新叫用的機制,其中 "searchMode": "any" 偏好重新叫用 (符合任何準則的文件會視為是相符項目),而「searchMode=all」則偏好精確度 (所有準則都必須在文件中比對)。

在布林搜尋的執行內容中,如果您以多個運算子堆疊查詢,並取得較廣泛的結果 (而非較狹隘的結果),預設 "searchMode": "any" 可能會造成混淆。 在使用 NOT 更是如此,因為其結果會包含所有「不包含」特定字詞的文件。

下列範例提供一個實例。 使用 searchMode (any) 執行下列查詢,會傳回 42 份文件:包含「restaurant」一詞的文件,加上沒有「air conditioning」片語的所有文件。

請注意,布林運算子 (-) 與片語「air conditioning」之間沒有空格。

POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
    "search": "restaurant -\"air conditioning\"",
    "searchMode": "any",
    "searchFields": "Tags",
    "select": "HotelId, HotelName, Tags",
    "count": true
}

變更為 "searchMode": "all" 會對準則強制執行累積效果,並傳回較小的結果集 (7 個相符項目),該結果集由包含「restaurant」一詞的文件減去包含片語「air conditioning」的文件組成。

查詢的回應看起來應該類似下列範例,為了簡潔起見進行了刪減。

"@odata.count": 7,
"value": [
    {
        "@search.score": 2.5460577,
        "HotelId": "11",
        "HotelName": "Regal Orb Resort & Spa",
        "Tags": [
            "free wifi",
            "restaurant",
            "24-hour front desk service"
        ]
    },
    {
        "@search.score": 2.166792,
        "HotelId": "10",
        "HotelName": "Countryside Hotel",
        "Tags": [
            "24-hour front desk service",
            "coffee in lobby",
            "restaurant"
        ]
    },
...

範例 8:分頁結果

在先前的範例中,您已了解影響搜尋結果組合的參數,包括 select,此參數可決定結果中的欄位、排序次序,以及如何包含所有相符項目的計數。 此範例是分頁參數形式之搜索結果組合的延續,可讓您批次處理出現在任何指定頁面中的結果數目。

根據預設,搜尋服務會傳回前 50 個相符項目。 若要控制每個頁面中的符合項目數,請使用 top 來定義批次的大小,然後使用 skip 來挑選後續的批次。

下列範例會在 Rating 欄位上使用篩選條件和排序次序 (Rating 欄位可同時進行篩選和排序),因為這樣能更容易看到對排序結果進行分頁的效果。 在一般完整搜尋查詢中,最符合的相符項目會依 @search.score 進行排名與分頁。

POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
    "search": "*",
    "filter": "Rating gt 4",
    "select": "HotelName, Rating",
    "orderby": "Rating desc",
    "top": "5",
    "count": true
}

此查詢會尋找 21 份相符文件,但因為您指定了 top,所以回應只會傳回前五個相符項目,且評等由 4.9 開始,並以 4.7 結束 (「Lady of the Lake B & B」)。

若要取得後續的 5 份文件,請略過第一個批次:

POST /indexes/hotels-sample-index/docs/search?api-version=2024-07-01
{
    "search": "*",
    "filter": "Rating gt 4",
    "select": "HotelName, Rating",
    "orderby": "Rating desc",
    "top": "5",
    "skip": "5",
    "count": true
}

第二個批次的回應會略過前五個相符項目,從「Pull'r Inn Motel」開始傳回接下來的五個相符項目。 若要繼續執行其他批次,請將 top 維持在 5,然後在每個新的要求上將 skip 依 5 遞增 (skip=5、skip=10、skip=15,依此類推)。

"value": [
    {
        "@search.score": 1.0,
        "HotelName": "Pull'r Inn Motel",
        "Rating": 4.7
    },
    {
        "@search.score": 1.0,
        "HotelName": "Sublime Cliff Hotel",
        "Rating": 4.6
    },
    {
        "@search.score": 1.0,
        "HotelName": "Antiquity Hotel",
        "Rating": 4.5
    },
    {
        "@search.score": 1.0,
        "HotelName": "Nordick's Motel",
        "Rating": 4.5
    },
    {
        "@search.score": 1.0,
        "HotelName": "Winter Panorama Resort",
        "Rating": 4.5
    }
]

下一步

現在您已使用基本查詢語法進行一些練習,請嘗試以程式碼指定查詢。 下列連結說明如何使用 Azure SDK 設定搜尋查詢。

您可以在下列連結中找到其他語法參考、查詢架構和範例: