教學課程:使用 REST 從 Azure 儲存體 編製巢狀 JSON Blob 的索引
Azure AI 搜尋服務可以使用知道如何讀取半結構化數據的索引器,在 Azure Blob 儲存體 中編製 JSON 檔和陣列的索引。 半結構化數據包含標記或標記,可分隔數據內的內容。 它會分割非結構化數據之間的差異,而非結構化數據必須完整編製索引,且正式結構化的數據會遵循數據模型,例如可依據每個字段編製索引的關係資料庫架構。
本教學課程說明如何編製巢狀 JSON 陣列的索引。 它會使用 REST 用戶端和 搜尋 REST API 來執行下列工作:
- 設定範例數據並設定
azureblob
數據源 - 建立 Azure AI 搜尋索引以包含可搜尋的內容
- 建立並執行索引器以讀取容器並擷取可搜尋的內容
- 搜尋您剛才建立的索引
如果您沒有 Azure 訂用帳戶,請在開始前建立免費帳戶。
必要條件
具有 REST 用戶端的 Visual Studio Code。
Azure AI 搜尋。 在您的 目前訂用帳戶下建立或 尋找現有的 Azure AI 搜尋資源 。
注意
您可以使用免費服務來進行本教學課程。 免費的搜尋服務會有限制,您只能使用三個索引、三個索引子和三個資料來源。 本教學課程會各建立一個。 開始之前,請確定您的服務有空間可接受新的資源。
下載檔案
下載範例數據存放庫的 ZIP 檔案,並擷取內容。 瞭解做法。
範例數據是包含 JSON 陣列和 1,521 個巢狀 JSON 元素的單一 JSON 檔案。 範例數據源自 Kaggle 上的 NY 愛樂樂團表演史 。 我們選擇了一個 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
。在 [設定> Keys] 底下,複製管理密鑰。 管理員 索引鍵可用來新增、修改和刪除物件。 有兩個可交換的系統管理密鑰。 複製任一個。
設定 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=2023-11-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://free-demo-search-svc.search.windows.net:443/datasources('ny-philharmonic-ds')?api-version=2023-11-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://free-demo-search-svc.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=2023-11-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=2023-11-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=2023-11-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://free-demo-search-svc.search.windows.net/indexes('ny-philharmonic-index')/$metadata#docs(*)",
"@odata.count": 1521,
"@search.nextPageParameters": {
"search": "*",
"count": true,
"skip": 50
},
"value": [
],
"@odata.nextLink": "https://free-demo-search-svc.search.windows.net/indexes/ny-philharmonic-index/docs/search?api-version=2023-11-01"
}
search
新增參數以搜尋字串。 select
新增參數以將結果限製為較少的欄位。 filter
新增 以進一步縮小搜尋範圍。
### Query the index
POST {{baseUrl}}/indexes/ny-philharmonic-index/docs/search?api-version=2023-11-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'"
}
回應中會傳回兩份檔。
針對篩選,您也可以使用邏輯運算符(以及或或,非)和比較運算元(eq、ne、gt、lt、ge、le)。 字串比較會區分大小寫。 如需詳細資訊和範例,請參閱 建立查詢。
注意
參數 $filter
只適用於在建立索引時標示為可篩選的欄位。
重設並重新執行
索引器可以重設、清除執行歷程記錄,以允許完整重新執行。 下列 GET 要求適用於重設,後面接著重新執行。
### Reset the indexer
POST {{baseUrl}}/indexers/ny-philharmonic-indexer/reset?api-version=2023-11-01 HTTP/1.1
api-key: {{apiKey}}
### Run the indexer
POST {{baseUrl}}/indexers/ny-philharmonic-indexer/run?api-version=2023-11-01 HTTP/1.1
api-key: {{apiKey}}
### Check indexer status
GET {{baseUrl}}/indexers/ny-philharmonic-indexer/status?api-version=2023-11-01 HTTP/1.1
api-key: {{apiKey}}
清除資源
如果您使用自己的訂用帳戶,當專案結束時,建議您移除不再需要的資源。 資源若繼續執行,將需付費。 您可以個別刪除資源,或刪除資源群組以刪除整組資源。
您可以使用入口網站來刪除索引、索引器和數據來源。
下一步
現在您已熟悉 Azure Blob 索引編製的基本概念,讓我們進一步瞭解 Azure 儲存體 中 JSON Blob 的索引器設定。