Petunjuk memodelkan jenis data kompleks di Azure Cognitive Search

Himpunan data eksternal yang digunakan untuk mengisi indeks Azure Cognitive Search dapat datang dalam berbagai bentuk. Terkadang data-data tersebut termasuk substruktur hierarkis atau berlapis. Contohnya mungkin mencakup beberapa alamat untuk satu pelanggan, beberapa warna dan ukuran untuk satu SKU, beberapa pembuat buku tunggal, dan sebagainya. Dalam istilah pemodelan, Anda mungkin melihat struktur ini disebut sebagai jenis data kompleks, majemuk, komposit atau agregat. Istilah Yang digunakan Azure Cognitive Search untuk konsep ini adalah jenis kompleks. Di Azure Cognitive Search, jenis kompleks dimodelkan menggunakan bidang kompleks. Bidang kompleks adalah bidang yang berisi anak (sub-bidang) yang bisa dari jenis data apa pun, termasuk jenis kompleks lainnya. Ini berfungsi dengan cara yang sama seperti jenis data terstruktur dalam bahasa pemrogram.

Bidang kompleks mewakili satu objek dalam dokumen, atau array objek, bergantung pada jenis data. Bidang jenis Edm.ComplexType mewakili satu objek, sedangkan bidang jenis Collection(Edm.ComplexType) mewakili array objek.

Azure Cognitive Search secara asli mendukung jenis kompleks dan koleksi. Jenis ini memungkinkan Anda untuk memodelkan hampir semua struktur JSON dalam indeks Azure Cognitive Search. Di versi API AZURE Cognitive Search sebelumnya, hanya rangkaian baris yang diratakan yang dapat diimpor. Pada versi terbaru, indeks Anda sekarang dapat lebih terkait erat dengan data sumber. Dengan kata lain, jika data sumber Anda memiliki jenis kompleks, indeks Anda juga dapat memiliki jenis kompleks.

Untuk memulai, kami sarankan Himpunan data Hotel, yang bisa Anda muat di wizard Impor data portal Microsoft Azure. Wizard mendeteksi jenis kompleks dalam sumber dan menyarankan skema indeks berdasarkan struktur yang terdeteksi.

Catatan

Dukungan untuk jenis kompleks menjadi tersedia secara umum mulai dari api-version=2019-05-06.

Jika solusi pencarian Anda dibangun berdasarkan penyelesaian sebelumnya himpunan data yang diratakan dalam koleksi, Anda harus mengubah indeks untuk menyertakan jenis kompleks seperti yang didukung dalam versi API terbaru. Untuk informasi selengkapnya tentang peningkatan versi API, lihat Meningkatkan ke versi REST API terbaru atau Meningkatkan ke versi .NET SDK terbaru.

Contoh struktur kompleks

Dokumen JSON berikut terdiri dari bidang sederhana dan bidang kompleks. Bidang kompleks, seperti Address dan Rooms, memiliki sub-bidang. Address memiliki himpunan nilai tunggal untuk sub-bidang tersebut, karena merupakan objek tunggal dalam dokumen. Sebaliknya, Rooms memiliki beberapa set nilai untuk sub-bidangnya, satu untuk setiap objek dalam koleksi.

{
  "HotelId": "1",
  "HotelName": "Secret Point Motel",
  "Description": "Ideally located on the main commercial artery of the city in the heart of New York.",
  "Tags": ["Free wifi", "on-site parking", "indoor pool", "continental breakfast"],
  "Address": {
    "StreetAddress": "677 5th Ave",
    "City": "New York",
    "StateProvince": "NY"
  },
  "Rooms": [
    {
      "Description": "Budget Room, 1 Queen Bed (Cityside)",
      "RoomNumber": 1105,
      "BaseRate": 96.99,
    },
    {
      "Description": "Deluxe Room, 2 Double Beds (City View)",
      "Type": "Deluxe Room",
      "BaseRate": 150.99,
    }
    . . .
  ]
}

Pengindeksan jenis kompleks

Selama pengindeksan, Anda dapat memiliki maksimal 3000 elemen di semua koleksi kompleks dalam satu dokumen. Elemen koleksi kompleks adalah anggota koleksi tersebut, jadi dalam kasus Rooms (satu-satunya koleksi kompleks dalam contoh Hotel), setiap kamar adalah elemen. Dalam contoh di atas, jika "Secret Point Motel" memiliki 500 kamar, dokumen hotel akan memiliki 500 elemen kamar. Untuk koleksi kompleks berlapis, setiap elemen berlapis juga dihitung, selain elemen luar (induk).

Batas ini hanya berlaku untuk koleksi kompleks, dan bukan jenis kompleks (seperti Alamat) atau koleksi untai (karakter) (seperti Tag).

Membuat bidang kompleks

Seperti definisi indeks apa pun, Anda dapat menggunakan portal, REST API, atau .NET SDK untuk membuat skema yang menyertakan jenis kompleks.

Contoh berikut memperlihatkan skema indeks JSON dengan bidang, koleksi, dan jenis kompleks sederhana. Perhatikan bahwa dalam jenis kompleks, setiap sub-bidang memiliki jenis dan mungkin memiliki atribut, seperti halnya bidang tingkat atas. Skema ini sesuai dengan contoh data di atas. Address adalah bidang kompleks yang bukan koleksi (hotel memiliki satu alamat). Rooms adalah bidang koleksi kompleks (hotel memiliki banyak kamar).

{
  "name": "hotels",
  "fields": [
    { "name": "HotelId", "type": "Edm.String", "key": true, "filterable": true },
    { "name": "HotelName", "type": "Edm.String", "searchable": true, "filterable": false },
    { "name": "Description", "type": "Edm.String", "searchable": true, "analyzer": "en.lucene" },
    { "name": "Address", "type": "Edm.ComplexType",
      "fields": [
        { "name": "StreetAddress", "type": "Edm.String", "filterable": false, "sortable": false, "facetable": false, "searchable": true },
        { "name": "City", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true },
        { "name": "StateProvince", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true }
      ]
    },
    { "name": "Rooms", "type": "Collection(Edm.ComplexType)",
      "fields": [
        { "name": "Description", "type": "Edm.String", "searchable": true, "analyzer": "en.lucene" },
        { "name": "Type", "type": "Edm.String", "searchable": true },
        { "name": "BaseRate", "type": "Edm.Double", "filterable": true, "facetable": true }
      ]
    }
  ]
}

Memperbarui bidang kompleks

Semua aturan pengindeksan ulang yang berlaku terhadap bidang secara umum masih berlaku untuk bidang kompleks. Pengulangan beberapa aturan utama di sini, penambahan bidang ke jenis kompleks tidak memerlukan pembangunan ulang indeks, tetapi sebagian besar modifikasi dilakukan.

Pembaruan struktural untuk definisi

Anda dapat menambahkan sub-bidang baru ke bidang kompleks kapan saja tanpa perlu membangun ulang indeks. Misalnya, menambahkan "ZipCode" ke Address atau "Amenities" ke Rooms diizinkan, sama seperti penambahan bidang tingkat atas ke indeks. Dokumen yang sudah ada memiliki nilai null untuk bidang baru hingga Anda secara eksplisit mengisi bidang tersebut dengan memperbarui data Anda.

Perhatikan bahwa dalam jenis kompleks, setiap sub-bidang memiliki jenis dan mungkin memiliki atribut, seperti halnya bidang tingkat atas

Pembaruan data

Memperbarui dokumen yang ada dalam indeks dengan tindakan upload berfungsi dengan cara yang sama untuk bidang kompleks dan sederhana - semua bidang diganti. Namun, merge (atau mergeOrUpload saat diterapkan ke dokumen yang sudah ada) tidak berfungsi sama di semua bidang. Secara khusus, merge tidak mendukung penggabungan elemen dalam koleksi. Batasan ini ada untuk koleksi jenis primitif dan koleksi kompleks. Untuk memperbarui koleksi, Anda harus mengambil nilai pengumpulan lengkap, membuat perubahan, lalu menyertakan koleksi baru dalam permintaan API Indeks.

Pencarian bidang kompleks

Ekspresi pencarian bentuk bebas berfungsi seperti yang diharapkan dengan jenis kompleks. Jika ada bidang atau sub-bidang yang dapat dicari di mana saja dalam dokumen yang cocok, maka dokumen itu sendiri cocok.

Kueri menjadi lebih bernuansa ketika Anda memiliki beberapa istilah dan operator, serta beberapa istilah memiliki nama bidang yang ditentukan, seperti yang dimungkinkan dengan sintaks Lucene. Misalnya, kueri ini mencoba untuk mencocokkan dua istilah, "Portland" dan "OR", terhadap dua sub-bidang dari bidang Alamat:

search=Address/City:Portland AND Address/State:OR

Kueri seperti ini tidak berkorelasi untuk pencarian teks lengkap, tidak seperti filter. Dalam filter, kueri di atas sub-bidang koleksi kompleks berkorelasi menggunakan variabel rentang di any atau all. Kueri Lucene di atas menampilkan dokumen yang berisi keduanya, baik "Portland, Maine" dan "Portland, Oregon", bersama dengan kota-kota lain di Oregon. Ini terjadi karena setiap klausa berlaku untuk semua nilai bidangnya di seluruh dokumen, sehingga tidak ada konsep "sub-dokumen saat ini". Untuk informasi selengkapnya tentang ini, lihat Memahami filter koleksi OData di Azure Cognitive Search.

Memilih bidang kompleks

Parameter $select digunakan untuk memilih bidang mana yang ditampilkan dalam hasil pencarian. Untuk menggunakan parameter ini untuk memilih sub-bidang tertentu dari bidang kompleks, sertakan bidang induk dan sub-bidang yang dipisahkan oleh garis miring (/).

$select=HotelName, Address/City, Rooms/BaseRate

Bidang harus ditandai sebagai Dapat Diambil dalam indeks jika Anda memerlukannya di hasil pencarian. Hanya bidang yang ditandai sebagai Dapat Diambil yang dapat digunakan dalam pernyataan $select.

Memfilter, memfaset, dan mengurutkan bidang kompleks

Sintaks jalur OData sama yang digunakan untuk pemfilteran dan pencarian bidang juga dapat digunakan untuk pemfasetani, pengurutan, dan pemilihan bidang dalam permintaan pencarian. Untuk jenis kompleks, berlaku aturan yang mengatur sub-bidang mana yang dapat ditandai sebagai dapat diurutkan atau dapat difasetkan. Untuk informasi selengkapnya tentang aturan ini, lihat Referensi membuat API Indeks.

Pemfasetan sub-bidang

Sub-bidang apa pun dapat ditandai sebagai dapat difasetkan kecuali sub-bidang tersebut jenis Edm.GeographyPoint atau Collection(Edm.GeographyPoint).

Jumlah dokumen yang ditampilkan dalam hasil faset dihitung untuk dokumen induk (hotel), bukan sub-dokumen dalam koleksi kompleks (rooms). Misalnya, anggap hotel memiliki 20 kamar jenis "suite". Mengingat parameter faset ini facet=Rooms/Type, jumlah faset akan menjadi satu untuk hotel, bukan 20 untuk kamar.

Mengurutkan bidang kompleks

Operasi pengurutan berlaku untuk dokumen (Hotel) dan bukan sub-dokumen (Rooms). Ketika Anda memiliki koleksi jenis kompleks, seperti Rooms, penting untuk menyadari bahwa Anda tidak dapat mengurutkan Rooms sama sekali. Bahkan, Anda tidak dapat mengurutkan koleksi apa pun.

Mengurutkan tugas operasi saat bidang memiliki nilai tunggal per dokumen, baik bidang tersebut merupakan bidang sederhana, atau sub-bidang dalam jenis kompleks. Misalnya, Address/City diperbolehkan untuk diurutkan karena hanya ada satu alamat per hotel, jadi $orderby=Address/City akan mengurutkan hotel menurut kota.

Pemfilteran pada bidang kompleks

Anda bisa merujuk ke sub-bidang dengan bidang kompleks dalam ekspresi filter. Cukup gunakan sintaks jalur OData yang sama yang digunakan untuk pemfasetan, pengurutan, dan pemilihan bidang. Misalnya, filter berikut akan menampilkan semua hotel di Kanada:

$filter=Address/Country eq 'Canada'

Untuk memfilter bidang koleksi kompleks, Anda bisa menggunakan ekspresi lambda dengan any dan all operator. Dalam kasus ini, variabel rentang ekspresi lambda adalah objek dengan sub-bidang. Anda dapat merujuk sub-bidang tersebut dengan sintaks jalur OData standar. Misalnya, filter berikut akan menampilkan semua hotel dengan setidaknya satu kamar deluxe dan semua kamar bebas asap rokok:

$filter=Rooms/any(room: room/Type eq 'Deluxe Room') and Rooms/all(room: not room/SmokingAllowed)

Seperti halnya bidang sederhana tingkat atas, sub-bidang sederhana bidang kompleks hanya dapat disertakan dalam filter jika sub-bidang tersebut memiliki atribut yang dapat difilter yang diatur ke true dalam definisi indeks. Untuk informasi selengkapnya, lihat Referensi membuat API Indeks.

Langkah berikutnya

Coba Himpunan data Hotel di wizard Impor data. Anda akan memerlukan informasi koneksi Cosmos DB yang disediakan dalam bacasaya untuk mengakses data.

Dengan informasi tersebut di tangan, langkah pertama Anda dalam wizard ini adalah membuat sumber data Azure Cosmos DB baru. Selanjutnya dalam wizard, saat Anda masuk ke halaman indeks target, Anda akan melihat indeks dengan jenis kompleks. Buat dan muat indeks ini, lalu jalankan kueri untuk memahami struktur baru.