Contoh kueri pencarian "sederhana" di Azure AI Search

Di Azure AI Search, sintaks kueri sederhana memanggil pengurai kueri default untuk pencarian teks lengkap. Pengurai cepat dan menangani skenario umum, termasuk pencarian teks lengkap, pencarian yang difilter dan tersaring, dan pencarian awalan. Artikel ini menggunakan contoh untuk mengilustrasikan penggunaan sintaksis sederhana dalam permintaan Pencarian Dokumen (REST API).

Catatan

Sintaksis kueri alternatif adalah Lucene Lengkap, yang mendukung struktur kueri yang lebih kompleks, seperti pencarian fuzzy dan kartubebas. Untuk informasi dan contoh selengkapnya, lihat Menggunakan sintaksis Lucene lengkap.

Indeks sampel hotel

Kueri berikut didasarkan pada indeks sampel hotel, yang dapat Anda buat dengan mengikuti instruksi dalam mulai cepat ini.

Contoh kueri diartikulasikan menggunakan permintaan REST API dan POST. Anda dapat menempelkan dan menjalankannya di klien REST. Atau, gunakan tampilan JSON Search Explorer di portal Azure. Dalam tampilan JSON, Anda bisa menempelkan contoh kueri yang diperlihatkan di sini dalam artikel ini.

Permintaan header harus memiliki nilai berikut:

Tombol Nilai
Content-Type application/json
api-key <your-search-service-api-key>, baik kueri atau kunci admin

Parameter URI harus menyertakan titik akhir layanan pencarian Anda dengan nama indeks, koleksi dokumen, perintah pencarian, dan versi API, mirip dengan contoh berikut:

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

Isi permintaan harus dibentuk sebagai JSON yang valid:

{
    "search": "*",
    "queryType": "simple",
    "select": "HotelId, HotelName, Category, Tags, Description",
    "count": true
}
  • "pencarian" yang diatur ke * adalah kueri yang tidak ditentukan, setara dengan pencarian null atau kosong. Ini tidak terlalu berguna, tetapi ini adalah pencarian paling sederhana yang dapat Anda lakukan, dan menunjukkan semua bidang yang dapat diambil dalam indeks, dengan semua nilai.

  • Pengaturan "queryType" ke "sederhana" adalah default dan dapat dihilangkan, tetapi disertakan untuk lebih memperkuat bahwa contoh kueri dalam artikel ini dinyatakan dalam sintaksis sederhana.

  • "pilih" yang diatur ke daftar bidang yang dipisahkan koma digunakan untuk komposisi hasil pencarian, termasuk hanya bidang yang berguna dalam konteks hasil pencarian.

  • "hitung" mengembalikan jumlah dokumen yang cocok dengan kriteria pencarian. Pada string pencarian kosong, jumlahnya adalah semua dokumen dalam indeks (50 di indeks sampel hotel).

Pencarian teks lengkap dapat berupa sejumlah istilah mandiri atau frase tertutup kutipan, dengan atau tanpa operator boolean.

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

Pencarian kata kunci yang terdiri dari istilah atau frasa penting cenderung berfungsi paling baik. Bidang string menjalani analisis teks selama pengindeksan dan kueri, menghilangkan kata-kata yang tidak penting seperti "the", "and", "it". Untuk melihat bagaimana untai kueri diberi token dalam indeks, teruskan untai dalam panggilan Analisis Teks ke indeks.

Parameter "searchMode" mengontrol presisi dan penarikan. Jika Anda ingin penarikan lebih banyak, gunakan nilai "apa pun" default, yang mengembalikan hasil jika ada bagian dari untai kueri yang cocok. Jika Anda menyukai presisi, di mana semua bagian untai harus dicocokkan, ubah searchMode menjadi "semua". Cobalah kueri di atas dengan kedua cara untuk melihat bagaimana searchMode mengubah hasilnya.

Respons untuk kueri "kolam renang spa +bandara" akan terlihat mirip dengan contoh berikut, dipangkas agar lebih singkat.

"@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"
        ]
    }
]

Perhatikan skor pencarian dalam respons. Ini adalah skor relevansi kecocokan. Secara default, layanan pencarian mengembalikan 50 kecocokan teratas berdasarkan skor ini.

Skor seragam "1.0" terjadi ketika tidak ada peringkat, baik karena pencarian tidak pencarian teks lengkap, atau karena tidak ada kriteria yang disediakan. Misalnya, dalam pencarian kosong (search=*), baris kembali dalam urutan arbitrer. Saat menyertakan kriteria aktual, Anda akan melihat skor pencarian berkembang menjadi nilai yang bermakna.

Contoh 2: Cari berdasarkan ID

Saat mengembalikan hasil pencarian dalam kueri, langkah logis berikutnya adalah menyediakan halaman detail yang menyertakan lebih banyak bidang dari dokumen. Contoh ini memperlihatkan kepada Anda cara mengembalikan satu dokumen menggunakan Dokumen Pencarian dengan meneruskan ID dokumen.

GET /indexes/hotels-sample-index/docs/41?api-version=2023-11-01

Semua dokumen memiliki pengidentifikasi unik. Jika Anda menggunakan portal, pilih indeks dari tab Indeks lalu lihat definisi bidang untuk menentukan bidang mana yang menjadi kuncinya. Menggunakan REST, panggilan Dapatkan Indeks mengembalikan definisi indeks di badan respons.

Respons untuk kueri di atas terdiri dari dokumen yang kuncinya adalah 41. Bidang apa pun yang ditandai sebagai "dapat diambil" dalam definisi indeks dapat dikembalikan dalam hasil pencarian dan dirender di aplikasi Anda.

{
    "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"
    }
}

Contoh 3: Memfilter teks

Sintaks filter adalah ekspresi OData yang dapat Anda gunakan dengan sendirinya atau dengan search. Digunakan bersama-sama, filter diterapkan terlebih dahulu ke seluruh indeks, lalu pencarian dilakukan pada hasil filter. Oleh karena itu, filter bisa menjadi teknik yang berguna untuk meningkatkan performa kueri karena mengurangi kumpulan dokumen yang perlu diproses oleh kueri pencarian.

Filter dapat didefinisikan pada bidang apa pun yang ditandai sebagai filterable dalam definisi indeks. Untuk indeks sampel hotel, bidang yang dapat difilter termasuk Kategori, Tag, ParkingIncluded, Peringkat, dan sebagian besar bidang Alamat.

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

Respons untuk kueri di atas hanya dilingkup ke hotel-hotel yang dikategorikan sebagai "Laporan dan Spa", dan itu termasuk istilah "seni" atau "tur". Dalam hal ini, hanya ada satu kecocokan.

{
    "@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"
}

Contoh 4: Memfilter fungsi

Ekspresi filter dapat mencakup fungsi "search.ismatch" dan "search.ismatchscoring", memungkinkan Anda menyusun kueri pencarian di dalam filter. Ekspresi filter ini menggunakan kartubebas gratis untuk memilih fasilitas termasuk wifi gratis, parkir gratis, dan sebagainya.

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

Tanggapan untuk kecocokan kueri di atas pada 19 hotel yang menawarkan fasilitas gratis. Perhatikan bahwa skor pencarian adalah seragam "1.0" di seluruh hasil. Ini karena ekspresi pencarian null atau kosong, yang mengakibatkan filter verbatim cocok, tetapi tidak ada pencarian teks lengkap. Skor relevansi hanya dikembalikan pada pencarian teks lengkap. Jika Anda menggunakan filter tanpa search, pastikan Anda memiliki bidang yang cukup dapat diurutkan sehingga Anda dapat mengontrol peringkat pencarian.

"@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"
        ]
    },

Contoh 5: Filter rentang

Pemfilteran rentang didukung melalui ekspresi filter untuk tipe data apa pun. Contoh berikut mengilustrasikan rentang numerik dan untai. Jenis data adalah hal yang penting dalam filter rentang dan bekerja paling baik saat data numerik berada dalam bidang numerik, dan untai data berada dalam bidang untai. Data numerik dalam bidang string tidak cocok untuk rentang karena string numerik tidak sebanding.

Kueri berikut ini adalah rentang numerik. Di indeks sampel hotel, satu-satunya bidang numerik yang dapat difilter adalah Peringkat.

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

Respons untuk kueri akan terlihat mirip dengan contoh berikut, dipangkas agar lebih singkat.

"@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
    }
...

Kueri berikutnya adalah filter rentang di atas bidang untai (Address/StateProvince):

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

Respons untuk kueri ini akan terlihat mirip dengan contoh di bawah ini, dipangkas agar lebih singkat. Dalam contoh ini, tidak dimungkinkan untuk mengurutkan menurut StateProvince karena bidang tidak dikaitkan sebagai "dapat diurutkan" dalam definisi indeks.

"@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 "
        }
    },
...

Indeks sampel hotel mencakup bidang Lokasi dengan koordinat garis lintang dan bujur. Contoh ini menggunakan fungsi geo.distance yang memfilter pada dokumen dalam lingkar titik awal, hingga jarak arbitrer (dalam kilometer) yang Anda sediakan. Anda bisa menyesuaikan nilai terakhir dalam kueri (10) untuk mengurangi atau memperbesar area permukaan kueri.

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

Respons untuk kueri ini mengembalikan semua hotel dalam jarak 10 kilometer dari koordinat yang disediakan:

{
    "@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"
            }
        }
    ]
}

Contoh 7: Booleans dengan searchMode

Sintaksis sederhana mendukung operator boolean dalam bentuk karakter ( +, -, | ) untuk mendukung logika kueri AND, OR, dan NOT. Pencarian Boolean berperilaku seperti yang Anda harapkan, dengan beberapa pengecualian penting.

Dalam contoh sebelumnya, searchMode parameter diperkenalkan sebagai mekanisme untuk menginfluensikan presisi dan pengenalan, dengan "searchMode": "any" mendukung pengenalan (dokumen yang memenuhi salah satu kriteria dianggap cocok), dan "searchMode=all" mendukung presisi (semua kriteria harus dicocokkan dalam dokumen).

Dalam konteks pencarian Boolean, defaultnya "searchMode": "any" bisa membingungkan jika Anda menumpuk kueri dengan beberapa operator dan mendapatkan hasil yang lebih luas alih-alih hasil yang lebih sempit. Ini terutama berlaku dengan NOT, di mana hasilnya mencakup semua dokumen "tidak berisi" istilah atau frasa tertentu.

Contoh berikut memberikan ilustrasi. Menjalankan kueri berikut dengan searchMode (apa pun), 42 dokumen dikembalikan: yang berisi istilah "restoran", ditambah semua dokumen yang tidak memiliki frasa "AC".

Perhatikan bahwa tidak ada ruang antara operator boolean (-) dan frasa "AC".

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

Mengubah untuk memberlakukan efek kumulatif pada kriteria dan mengembalikan tataan hasil yang lebih kecil (7 kecocokan "searchMode": "all" ) yang terdiri dari dokumen yang berisi istilah "restoran", dikurangi yang berisi frasa "AC".

Respons untuk kueri akan terlihat mirip dengan contoh berikut, dipangkas agar lebih singkat.

"@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"
        ]
    },
...

Contoh 8: Hasil penomoran

Dalam contoh sebelumnya, Anda mempelajari tentang parameter yang memengaruhi komposisi hasil pencarian, termasuk select yang menentukan bidang mana yang dalam hasil, urutan pengurutan, dan cara menyertakan hitungan semua kecocokan. Contoh ini adalah kelanjutan dari komposisi hasil pencarian dalam bentuk parameter penomoran yang memungkinkan Anda untuk mengelompokkan jumlah hasil yang muncul di halaman tertentu.

Secara default, layanan pencarian mengembalikan 50 kecocokan teratas. Untuk mengontrol jumlah kecocokan di setiap halaman, gunakan top untuk menentukan ukuran batch, lalu gunakan skip untuk mengambil batch berikutnya.

Contoh berikut menggunakan filter dan urutan sortir pada bidang Peringkat (Peringkat dapat difilter dan dapat diurutkan) karena lebih mudah untuk melihat efek penomoran pada hasil yang diurutkan. Dalam kueri pencarian penuh reguler, kecocokan teratas diberi peringkat dan di halaman oleh @search.score.

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

Kueri menemukan 21 dokumen yang cocok, tetapi karena Anda menentukan , respons hanya mengembalikan lima kecocokan topteratas, dengan peringkat mulai dari 4,9, dan berakhir pada 4,7 dengan "Lady of the Lake B & B".

Untuk mendapatkan 5 berikutnya, lompati batch pertama:

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

Respon untuk batch kedua melompati lima kecocokan pertama, mengembalikan lima kecocokan berikutnya, dimulai dengan "Pull'r Inn Motel". Untuk melanjutkan dengan lebih banyak batch, Anda akan menyimpan top di 5, dan kemudian bertambah skip 5 pada setiap permintaan baru (skip=5, skip=10, skip=15, dan sebagainya).

"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
    }
]

Langkah berikutnya

Sekarang setelah Anda berlatih sintaksis kueri dasar, coba tentukan kueri dalam kode. Tautan berikut mencakup cara menyiapkan kueri pencarian menggunakan Azure SDK.

Referensi sintaks lainnya, arsitektur kueri, dan contoh dapat ditemukan di tautan berikut: