教學課程:使用 REST 為 Azure 儲存體中的巢狀 JSON Blob 編製索引
Azure AI 搜尋服務可以在 Azure Blob 儲存體中,使用索引子來為 JSON 文件和陣列編製索引,以了解如何讀取半結構化資料。 半結構化資料會包含在資料內分隔內容的標籤或標記。 這些資料會將不同的內容區分為必須完整編製索引的未結構化資料,以及遵循資料模型 (例如關聯式資料庫結構描述) 且可依據欄位逐一編製索引的正式結構化資料。
本教學課程說明如何為巢狀 JSON 陣列編製索引。 它會使用 REST 用戶端和搜尋服務 REST API 來執行下列工作:
- 設定範例資料並設定
azureblob
資料來源 - 建立 Azure AI 搜尋服務索引以包含可搜尋的內容
- 建立並執行索引子以讀取容器,並擷取可搜尋的內容
- 搜尋剛剛建立的索引
如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶。
必要條件
Azure AI 搜尋服務 (部分機器翻譯) 在您的目前訂用帳戶下建立或尋找現有的 Azure AI 搜尋服務資源。
注意
您可以使用免費服務來進行本教學課程。 免費的搜尋服務會有限制,您只能使用三個索引、三個索引子和三個資料來源。 本教學課程會各建立一個。 開始之前,請確定您的服務有空間可接受新的資源。
下載檔案
下載範例資料存放庫的 ZIP 檔案,並擷取內容。 了解作法。
範例資料是包含 JSON 陣列和 1,521 個巢狀 JSON 元素的單一 JSON 檔案。 範例資料來源為 Kaggle 上的紐約愛樂管弦樂團表演史。 我們選擇了一個 JSON 檔案,以保持在免費層的儲存體限制內。
以下是檔案中的第一個巢狀 JSON。 檔案的其餘部分包含 1,520 個其他音樂會表演實例。
{
"id": "7358870b-65c8-43d5-ab56-514bde52db88-0.1",
"programID": "11640",
"orchestra": "New York Philharmonic",
"season": "2011-12",
"concerts": [
{
"eventType": "Non-Subscription",
"Location": "Manhattan, NY",
"Venue": "Avery Fisher Hall",
"Date": "2011-09-07T04:00:00Z",
"Time": "7:30PM"
},
{
"eventType": "Non-Subscription",
"Location": "Manhattan, NY",
"Venue": "Avery Fisher Hall",
"Date": "2011-09-08T04:00:00Z",
"Time": "7:30PM"
}
],
"works": [
{
"ID": "5733*",
"composerName": "Bernstein, Leonard",
"workTitle": "WEST SIDE STORY (WITH FILM)",
"conductorName": "Newman, David",
"soloists": []
},
{
"ID": "0*",
"interval": "Intermission",
"soloists": []
}
]
}
將範例資料上傳至 Azure 儲存體
在 Azure 儲存體中,建立新的容器並命名為 ny-philmonic-free。
取得儲存體連接字串,以便在 Azure AI 搜尋服務中制訂連線。
在左側,選取 [存取金鑰]。
複製金鑰一或金鑰二的連接字串。 連接字串應類似於下列範例:
DefaultEndpointsProtocol=https;AccountName=<your account name>;AccountKey=<your account key>;EndpointSuffix=core.windows.net
複製搜尋服務 URL 與 API 金鑰
在本教學課程中,Azure AI 搜尋服務的連線需要端點和 API 金鑰。 您可以從 Azure 入口網站取得這些值。
登入 Azure 入口網站,瀏覽至搜尋服務的 [概觀] 頁面,然後複製 URL。 範例端點看起來會像是
https://mydemo.search.windows.net
。在 [設定 > 金鑰] 下面,複製系統管理金鑰。 系統管理金鑰可用來新增、修改和刪除物件。 有兩個可交換的系統管理密鑰。 複製任一個。
設定 REST 檔案
啟動 Visual Studio Code 並建立新的檔案
提供要求中使用的變數值:
@baseUrl = PUT-YOUR-SEARCH-SERVICE-ENDPOINT-HERE @apiKey = PUT-YOUR-ADMIN-API-KEY-HERE @storageConnection = PUT-YOUR-STORAGE-CONNECTION-STRING-HERE @blobContainer = PUT-YOUR-CONTAINER-NAME-HERE
使用
.rest
或.http
副檔名來儲存檔案。
如果您需要使用 REST 用戶端的協助,請參閱快速入門:使用 REST 進行文字搜尋。
建立資料來源
建立資料來源 (REST) 會建立資料來源連線,指定要編製索引的資料。
### Create a data source
POST {{baseUrl}}/datasources?api-version=2024-07-01 HTTP/1.1
Content-Type: application/json
api-key: {{apiKey}}
{
"name" : "ny-philharmonic-ds",
"description": null,
"type": "azureblob",
"subtype": null,
"credentials": {
"connectionString": "{{storageConnectionString}}"
},
"container": {
"name": "{{blobContainer}}",
"query": null
},
"dataChangeDetectionPolicy": null,
"dataDeletionDetectionPolicy": null
}
傳送要求。 回應看起來應如下所示:
HTTP/1.1 201 Created
Transfer-Encoding: chunked
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
ETag: "0x8DC43A5FDB8448F"
Location: https://<YOUR-SEARCH-SERVICE-NAME>.search.windows.net:443/datasources('ny-philharmonic-ds')?api-version=2024-07-01
Server: Microsoft-IIS/10.0
Strict-Transport-Security: max-age=2592000, max-age=15724800; includeSubDomains
Preference-Applied: odata.include-annotations="*"
OData-Version: 4.0
request-id: 7ca53f73-1054-4959-bc1f-616148a9c74a
elapsed-time: 111
Date: Wed, 13 Mar 2024 21:38:58 GMT
Connection: close
{
"@odata.context": "https://<YOUR-SEARCH-SERVICE-NAME>.search.windows.net/$metadata#datasources/$entity",
"@odata.etag": "\"0x8DC43A5FDB8448F\"",
"name": "ny-philharmonic-ds",
"description": null,
"type": "azureblob",
"subtype": null,
"credentials": {
"connectionString": null
},
"container": {
"name": "ny-philharmonic-free",
"query": null
},
"dataChangeDetectionPolicy": null,
"dataDeletionDetectionPolicy": null,
"encryptionKey": null
}
建立索引
建立索引 (REST) 會在您的搜尋服務上建立搜尋索引。 索引會指定所有參數及其屬性。
對於巢狀 JSON,索引欄位必須與來源欄位相同。 目前,Azure AI 搜尋不支援欄位對應至巢狀 JSON。 因此,欄位名稱和資料類型必須完全相符。 下列索引會對齊原始內容中的 JSON 元素。
### Create an index
POST {{baseUrl}}/indexes?api-version=2024-07-01 HTTP/1.1
Content-Type: application/json
api-key: {{apiKey}}
{
"name": "ny-philharmonic-index",
"fields": [
{"name": "programID", "type": "Edm.String", "key": true, "searchable": true, "retrievable": true, "filterable": true, "facetable": true, "sortable": true},
{"name": "orchestra", "type": "Edm.String", "searchable": true, "retrievable": true, "filterable": true, "facetable": true, "sortable": true},
{"name": "season", "type": "Edm.String", "searchable": true, "retrievable": true, "filterable": true, "facetable": true, "sortable": true},
{ "name": "concerts", "type": "Collection(Edm.ComplexType)",
"fields": [
{ "name": "eventType", "type": "Edm.String", "searchable": true, "retrievable": true, "filterable": false, "sortable": false, "facetable": false},
{ "name": "Location", "type": "Edm.String", "searchable": true, "retrievable": true, "filterable": true, "sortable": false, "facetable": true },
{ "name": "Venue", "type": "Edm.String", "searchable": true, "retrievable": true, "filterable": true, "sortable": false, "facetable": true },
{ "name": "Date", "type": "Edm.String", "searchable": false, "retrievable": true, "filterable": true, "sortable": false, "facetable": true },
{ "name": "Time", "type": "Edm.String", "searchable": false, "retrievable": true, "filterable": true, "sortable": false, "facetable": true }
]
},
{ "name": "works", "type": "Collection(Edm.ComplexType)",
"fields": [
{ "name": "ID", "type": "Edm.String", "searchable": true, "retrievable": true, "filterable": false, "sortable": false, "facetable": false},
{ "name": "composerName", "type": "Edm.String", "searchable": true, "retrievable": true, "filterable": true, "sortable": false, "facetable": true },
{ "name": "workTitle", "type": "Edm.String", "searchable": true, "retrievable": true, "filterable": true, "sortable": false, "facetable": true },
{ "name": "conductorName", "type": "Edm.String", "searchable": true, "retrievable": true, "filterable": true, "sortable": false, "facetable": true },
{ "name": "soloists", "type": "Collection(Edm.String)", "searchable": true, "retrievable": true, "filterable": true, "sortable": false, "facetable": true }
]
}
]
}
重點︰
您無法使用欄位對應來協調欄位名稱或資料類型的差異。 此索引結構描述旨在鏡像原始內容。
巢狀 JSON 會模型化為
Collection(Edm.ComplextType)
。 在原始內容中,每一季都會有多個音樂會,而每個音樂會都會有多個作品。 若要容納此結構,請使用複雜類型的集合。在原始內容中,
Date
和Time
是字串,因此索引中的對應資料類型也是字串。
建立並執行索引子
建立索引子會在您的搜尋服務上建立索引子。 索引子會連接至資料來源、載入資料並編製索引,以及選擇性地提供排程來將資料重新整理自動化。
索引子設定包含 jsonArray
剖析模式和 documentRoot
。
### Create and run an indexer
POST {{baseUrl}}/indexers?api-version=2024-07-01 HTTP/1.1
Content-Type: application/json
api-key: {{apiKey}}
{
"name" : "ny-philharmonic-indexer",
"dataSourceName" : "ny-philharmonic-ds",
"targetIndexName" : "ny-philharmonic-index",
"parameters" : {
"configuration" : {
"parsingMode" : "jsonArray", "documentRoot": "/programs"}
},
"fieldMappings" : [
]
}
重點︰
原始內容檔案包含 JSON 陣列 (
"programs"
) 與 1,526 個巢狀 JSON 結構。 將parsingMode
設定為jsonArray
,以告知索引子每個 Blob 都包含一個 JSON 陣列。 因為巢狀 JSON 是從下一層開始,請將documentRoot
設定為/programs
。索引子執行需要數分鐘時間。 請等候索引子執行完成,再執行任何查詢。
執行查詢
第一個文件載入後,您就可以開始查詢。
### Query the index
POST {{baseUrl}}/indexes/ny-philharmonic-index/docs/search?api-version=2024-07-01 HTTP/1.1
Content-Type: application/json
api-key: {{apiKey}}
{
"search": "*",
"count": true
}
傳送要求。 這是未指定的全文檢索搜尋查詢,會傳回所有在索引中標記為可擷取的欄位,以及文件計數。 回應看起來應如下所示:
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true; charset=utf-8
Content-Encoding: gzip
Vary: Accept-Encoding
Server: Microsoft-IIS/10.0
Strict-Transport-Security: max-age=2592000, max-age=15724800; includeSubDomains
Preference-Applied: odata.include-annotations="*"
OData-Version: 4.0
request-id: a95c4021-f7b4-450b-ba55-596e59ecb6ec
elapsed-time: 106
Date: Wed, 13 Mar 2024 22:09:59 GMT
Connection: close
{
"@odata.context": "https://<YOUR-SEARCH-SERVICE-NAME>.search.windows.net/indexes('ny-philharmonic-index')/$metadata#docs(*)",
"@odata.count": 1521,
"@search.nextPageParameters": {
"search": "*",
"count": true,
"skip": 50
},
"value": [
],
"@odata.nextLink": "https://<YOUR-SEARCH-SERVICE-NAME>.search.windows.net/indexes/ny-philharmonic-index/docs/search?api-version=2024-07-01"
}
新增 search
參數以搜尋字串。 新增 select
參數,將結果限定為較少的欄位。 新增 filter
以進一步縮小搜尋範圍。
### Query the index
POST {{baseUrl}}/indexes/ny-philharmonic-index/docs/search?api-version=2024-07-01 HTTP/1.1
Content-Type: application/json
api-key: {{apiKey}}
{
"search": "puccini",
"count": true,
"select": "season, concerts/Date, works/composerName, works/workTitle",
"filter": "season gt '2015-16'"
}
回應會傳回兩份文件。
在篩選中,您也可以使用邏輯運算子 (and、or、not) 和比較運算子 (eq、ne、gt、lt、ge、le)。 字串比較是區分大小寫的。 如需詳細資訊和範例,請參閱建立查詢。
注意
$filter
參數只能在索引建立時標記為可篩選的欄位中使用。
重設並重新執行
您可以重設索引子,清除執行歷程記錄,以便允許完全重新執行。 下列 GET 要求適用於重設,然後接著重新執行。
### Reset the indexer
POST {{baseUrl}}/indexers/ny-philharmonic-indexer/reset?api-version=2024-07-01 HTTP/1.1
api-key: {{apiKey}}
### Run the indexer
POST {{baseUrl}}/indexers/ny-philharmonic-indexer/run?api-version=2024-07-01 HTTP/1.1
api-key: {{apiKey}}
### Check indexer status
GET {{baseUrl}}/indexers/ny-philharmonic-indexer/status?api-version=2024-07-01 HTTP/1.1
api-key: {{apiKey}}
清除資源
如果您使用自己的訂用帳戶,當專案結束時,建議您移除不再需要的資源。 資源若繼續執行,將需付費。 您可以個別刪除資源,或刪除資源群組以刪除整組資源。
您可以使用入口網站來刪除索引、索引子和資料來源。
下一步
現在您已熟悉 Azure Blob 索引編製的基本概念,接下來我們將進一步了解 Azure 儲存體中 JSON Blob 的索引子設定。