共用方式為


教學課程:使用 REST 為 Azure 儲存體中的巢狀 Markdown Blob 編製索引

附註

此功能目前處於公開預覽。 此預覽版在沒有服務等級協議的情況下提供,不建議用於生產工作負載。 可能不支援特定功能,或可能已經限制功能。 如需詳細資訊,請參閱 Microsoft Azure 預覽版增補使用條款

Azure AI 搜尋服務在 Azure Blob 儲存體中可以使用索引器編制 Markdown 文件和陣列的索引,該索引器了解如何讀取 Markdown 數據。

這個教學會教你如何使用 oneToManySearch Service REST APIs 索引 Markdown 檔案。

在本教學課程中,您會:

  • 設定範例資料並設定 azureblob 資料來源
  • 建立 Azure AI 搜尋服務索引以包含可搜尋的內容
  • 建立並執行索引子以讀取容器,並擷取可搜尋的內容
  • 搜尋剛剛建立的索引

必要條件

附註

您可以使用免費搜尋服務來進行本教學。 免費層會將您限制為三個索引、三個索引器和三個數據源。 本教學課程會各建立一個。 在開始之前,請確保你的服務有空間接受新資源。

準備範例資料

建立一個 Markdown 檔案

將下列 Markdown 複製並貼到名為 的 sample_markdown.md檔案中。 範例數據是包含各種 Markdown 元素的單一 Markdown 檔案。 我們選擇了一個 Markdown 檔案,以保持在免費層的儲存限制之下。

# Project Documentation

## Introduction
This document provides a complete overview of the **Markdown Features** used within this project. The following sections demonstrate the richness of Markdown formatting, with examples of lists, tables, links, images, blockquotes, inline styles, and more.

---

## Table of Contents
1. [Headers](#headers)
2. [Introduction](#introduction)
3. [Basic Text Formatting](#basic-text-formatting)
4. [Lists](#lists)
5. [Blockquotes](#blockquotes)
6. [Images](#images)
7. [Links](#links)
8. [Tables](#tables)
9. [Code Blocks and Inline Code](#code-blocks-and-inline-code)
10. [Horizontal Rules](#horizontal-rules)
11. [Inline Elements](#inline-elements)
12. [Escaping Characters](#escaping-characters)
13. [HTML Elements](#html-elements)
14. [Emojis](#emojis)
15. [Footnotes](#footnotes)
16. [Task Lists](#task-lists)
17. [Conclusion](#conclusion)

---

## Headers
Markdown supports six levels of headers. Use `#` to create headers:
"# Project Documentation" at the top of the document is an example of an h1 header.
"## Headers" above is an example of an h2 header.
### h3 example
#### h4 example
##### h5 example
###### h6 example
This is an example of content underneath a header.

## Basic Text Formatting
You can apply various styles to your text:
- **Bold**: Use double asterisks or underscores: `**bold**` or `__bold__`.
- *Italic*: Use single asterisks or underscores: `*italic*` or `_italic_`.
- ~~Strikethrough~~: Use double tildes: `~~strikethrough~~`.

## Lists

### Ordered List
1. First item  
2. Second item  
3. Third item  

### Unordered List
- Item A  
- Item B  
- Item C  

### Nested List
1. Parent item  
   - Child item  
   - Child item  

## Blockquotes
> This is a blockquote.  
> Blockquotes are great for emphasizing important information.  
>> Nested blockquotes are also possible!

## Images
![Markdown Logo](https://markdown-here.com/img/icon256.png)

## Links
[Visit Markdown Guide](https://www.markdownguide.org)

## Tables

| Syntax      | Description | Example       |
|-------------|-------------|---------------|
| Header      | Title       | Header Cell   |
| Paragraph   | Text block  | Row Content   |

## Code Blocks and Inline Code

### Inline Code
Use backticks to create `inline code`.

### Code Block
```javascript
// JavaScript example
function greet(name) {
  console.log(`Hello, ${name}!`);
}
greet('World');
```

## Horizontal Rules
Use three or more dashes or underscores to create a horizontal rule.

---
___

## Inline Elements
Sometimes, it’s useful to include `inline code` to highlight code-like content.  

You can also emphasize text like *this* or make it **bold**.

## Escaping Characters
To render special Markdown characters, use backslashes:
- \*Asterisks\*
- \#Hashes\#
- \[Brackets\]

## HTML Elements
You can mix HTML tags with Markdown:

<table>
  <tr>
    <th>HTML Table</th>
    <th>With Markdown</th>
  </tr>
  <tr>
    <td>Row 1</td>
    <td>Data 1</td>
  </tr>
</table>

## Emojis
Markdown supports some basic emojis:
- :smile: 😄  
- :rocket: 🚀  
- :checkered_flag: 🏁  

## Footnotes
This is an example of a footnote[^1]. Footnotes allow you to add notes without cluttering the main text.

[^1]: This is the content of the footnote.

## Task Lists
- [x] Complete the introduction  
- [ ] Add more examples  
- [ ] Review the document 

## Conclusion
Markdown is a lightweight yet powerful tool for writing documentation. It supports a variety of formatting options while maintaining simplicity and readability.

Thank you for reviewing this example!

上傳檔案並取得一個連線字串

請依 照以下指示 將檔案上傳 sample_markdown.md 到你的 Azure Storage 帳號中的容器。 你也必須取得儲存帳戶的連結字串。 記下連接字串和容器名稱,方便日後使用。

複製搜尋服務 URL 與 API 金鑰

在本教學課程中,Azure AI 搜尋服務的連線需要端點和 API 金鑰。 您可以從 Azure 入口網站取得這些值。 如需替代的連線方法,請參閱 受控識別

  1. 登入 Azure 入口網站 ,然後選取您的搜尋服務。

  2. 從左窗格中,選取 [ 概觀]。

  3. 記下 URL,它應該看起來像 https://my-service.search.windows.net

  4. 從左窗格中,選取 [設定]>[金鑰]

  5. 記得要用管理員金鑰來取得服務的完整權限。 可互換的管理金鑰有兩個,可在您需要變換金鑰時提供商務持續性。 你可以在新增、修改和刪除物件的請求中使用任一鍵。

    Azure 入口網站中 URL 和 API 金鑰的螢幕擷取畫面。

設定 REST 檔案

  1. 用 Visual Studio Code 建立一個檔案。

  2. 提供要求中使用的變數值。

    @baseUrl = PUT-YOUR-SEARCH-SERVICE-ENDPOINT-HERE
    @apiKey = PUT-YOUR-ADMIN-API-KEY-HERE
    @storageConnectionString = PUT-YOUR-STORAGE-CONNECTION-STRING-HERE
    @blobContainer = PUT-YOUR-CONTAINER-NAME-HERE
    
  3. 使用 .rest.http 副檔名來儲存檔案。

如需 REST 用戶端的說明,請參閱 快速入門:使用 REST 進行全文搜索

建立資料來源

建立資料來源 (REST) 會建立資料來源連線,指定要編製索引的資料。

### Create a data source
POST {{baseUrl}}/datasources?api-version=2025-09-01  HTTP/1.1
Content-Type: application/json
api-key: {{apiKey}}

{
    "name" : "sample-markdown-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: "0x8DCF52E926A3C76"
Location: https://<YOUR-SEARCH-SERVICE-NAME>.search.windows.net:443/datasources('sample-markdown-ds')?api-version=2025-09-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: 0714c187-217e-4d35-928a-5069251e5cba
elapsed-time: 204
Date: Fri, 25 Oct 2024 19:52:35 GMT
Connection: close

{
  "@odata.context": "https://<YOUR-SEARCH-SERVICE-NAME>.search.windows.net/$metadata#datasources/$entity",
  "@odata.etag": "\"0x8DCF52E926A3C76\"",
  "name": "sample-markdown-ds",
  "description": null,
  "type": "azureblob",
  "subtype": null,
  "credentials": {
    "connectionString": null
  },
  "container": {
    "name": "markdown-container",
    "query": null
  },
  "dataChangeDetectionPolicy": null,
  "dataDeletionDetectionPolicy": null,
  "encryptionKey": null,
  "identity": null
}

建立索引

建立索引 (REST) 會在您的搜尋服務上建立搜尋索引。 索引會指定所有欄位及其屬性。

在一對多剖析中,搜尋文件會定義關聯性中的「多」端。 您在索引中指定的欄位會決定搜尋檔案的結構。

您只需要為剖析器支援的 Markdown 元素準備欄位。 這些欄位是:

  • content:字串,根據文件中特定位置的標頭中繼資料,會包含在該特定位置找到的原始 Markdown。

  • sections:物件,包含直到所需標頭層級為止的標頭中繼資料子欄位。 例如,當markdownHeaderDepth設為h3時,會包含字串欄位h1h2h3。 這些欄位會透過在索引中鏡像此結構,或透過格式如 /sections/h1sections/h2 等的欄位映射來編制索引。如需具體情境下的範例,請參閱下列範例中的索引和索引器配置。 包含的子欄位如下:

    • h1 - 包含 h1 標頭值的字串。 如果目前檔中未設定,則為空字串。
    • (選擇性) h2- 包含 h2 標頭值的字串。 如果目前檔中未設定,則為空字串。
    • (選擇性) h3- 包含 h3 標頭值的字串。 如果目前檔中未設定,則為空字串。
    • (選擇性) h4- 包含 h4 標頭值的字串。 如果目前檔中未設定,則為空字串。
    • (選擇性) h5- 包含 h5 標頭值的字串。 如果目前檔中未設定,則為空字串。
    • (選擇性) h6- 包含 h6 標頭值的字串。 如果目前檔中未設定,則為空字串。
  • ordinal_position:整數值,表示區段在文件階層中的位置。 此欄位用於依據區段在文件中出現的原始順序對其進行排序,從序數位置 1 開始,並依序遞增每個內容區塊。

此實作會使用索引子中的欄位對應,將擴充的內容對應到索引。 如需剖析的一對多文件結構的詳細資訊,請參閱編製索引 Markdown Blob

此範例提供如何使用和不使用字段對應來為數據編製索引的範例。 在此情況下,我們知道包含 h1 文件的標題,因此我們可以將它對應至名為 title的欄位。 我們也會分別將 h2h3 欄位對應至 h2_subheaderh3_subheadercontentordinal_position 欄位不需要對應,因為它們會直接從 Markdown 擷取到使用這些名稱的欄位。 如需不需要欄位對應的完整索引架構範例,請參閱本節結尾。

### Create an index
POST {{baseUrl}}/indexes?api-version=2025-09-01  HTTP/1.1
Content-Type: application/json
api-key: {{apiKey}}

{
  "name": "sample-markdown-index",  
  "fields": [
    {"name": "id", "type": "Edm.String", "key": true, "searchable": true, "retrievable": true, "filterable": true, "facetable": true, "sortable": true},
    {"name": "content", "type": "Edm.String", "key": false, "searchable": true, "retrievable": true, "filterable": true, "facetable": true, "sortable": true},
    {"name": "title", "type": "Edm.String", "searchable": true, "retrievable": true, "filterable": true, "facetable": true, "sortable": true},
    {"name": "h2_subheader", "type": "Edm.String", "searchable": true, "retrievable": true, "filterable": true, "facetable": true, "sortable": true},
    {"name": "h3_subheader", "type": "Edm.String", "searchable": true, "retrievable": true, "filterable": true, "facetable": true, "sortable": true},
    {"name": "ordinal_position", "type": "Edm.Int32", "searchable": false, "retrievable": true, "filterable": true, "facetable": true, "sortable": true}
  ]
}

無欄位對應設定中的索引結構描述

欄位對應可讓您操作和篩選擴充的內容,以符合您希望的索引格式。 不過,您可能只想直接取得擴充的內容。 在此情況下,架構看起來會像這樣:

{
  "name": "sample-markdown-index",
  "fields": [
    {"name": "id", "type": "Edm.String", "key": true, "searchable": true, "retrievable": true, "filterable": true, "facetable": true, "sortable": true},
    {"name": "content", "type": "Edm.String", "key": false, "searchable": true, "retrievable": true, "filterable": true, "facetable": true, "sortable": true},
    {"name": "sections", 
      "type": "Edm.ComplexType", 
      "fields": [
        {"name": "h1", "type": "Edm.String", "searchable": true, "retrievable": true, "filterable": true, "facetable": true, "sortable": true},
        {"name": "h2", "type": "Edm.String", "searchable": true, "retrievable": true, "filterable": true, "facetable": true, "sortable": true},
        {"name": "h3", "type": "Edm.String", "searchable": true, "retrievable": true, "filterable": true, "facetable": true, "sortable": true}
      ]
    },
    {"name": "ordinal_position", "type": "Edm.Int32", "searchable": false, "retrievable": true, "filterable": true, "facetable": true, "sortable": true}
  ]
}

再重申一次,我們在 sections 物件中最多有 h3 個子欄位,因為 markdownHeaderDepth 設定為 h3

如果您使用此架構,請務必據此調整後續要求。 這需要從索引器組態中移除欄位對應,並更新搜尋查詢以使用對應的欄位名稱。

建立並執行索引子

建立索引子會在您的搜尋服務上建立索引子。 索引子會連接至資料來源、載入資料並編製索引,以及選擇性地提供排程來將資料重新整理自動化。

### Create and run an indexer
POST {{baseUrl}}/indexers?api-version=2025-09-01  HTTP/1.1
Content-Type: application/json
api-key: {{apiKey}}

{
  "name": "sample-markdown-indexer",
  "dataSourceName": "sample-markdown-ds",
  "targetIndexName": "sample-markdown-index",
  "parameters" : { 
    "configuration": { 
      "parsingMode": "markdown",
      "markdownParsingSubmode": "oneToMany",
      "markdownHeaderDepth": "h3"
      }
    },
  "fieldMappings" : [ 
    {
      "sourceFieldName": "/sections/h1",
      "targetFieldName": "title",
      "mappingFunction": null
    }
  ]
}

重點︰

  • 索引器只會解析標頭至 h3。 任何較低層級的標頭(h4h5h6)都會被視為純文字,並會顯示在 content 欄位中。 這就是為什麼索引和欄位對應只存在最多 h3 的深度。

  • contentordinal_position 欄位不需要任何欄位對應,因為它們在擴充的內容中以這些名稱存在。

執行查詢

第一個文件載入後,您就可以開始查詢。

### Query the index
POST {{baseUrl}}/indexes/sample-markdown-index/docs/search?api-version=2025-09-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: 6b94e605-55e8-47a5-ae15-834f926ddd14
elapsed-time: 77
Date: Fri, 25 Oct 2024 20:22:58 GMT
Connection: close

{
  "@odata.context": "https://<YOUR-SEARCH-SERVICE-NAME>.search.windows.net/indexes('sample-markdown-index')/$metadata#docs(*)",
  "@odata.count": 22,
  "value": [
    <22 search documents here>
  ]
}

新增 search 參數以搜尋字串。

### Query the index
POST {{baseUrl}}/indexes/sample-markdown-index/docs/search?api-version=2025-09-01  HTTP/1.1
Content-Type: application/json
api-key: {{apiKey}}
  
{
  "search": "h4",
  "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: ec5d03f1-e3e7-472f-9396-7ff8e3782105
elapsed-time: 52
Date: Fri, 25 Oct 2024 20:26:29 GMT
Connection: close

{
  "@odata.context": "https://<YOUR-SEARCH-SERVICE-NAME>.search.windows.net/indexes('sample-markdown-index')/$metadata#docs(*)",
  "@odata.count": 1,
  "value": [
    {
      "@search.score": 0.8744742,
      "section_id": "aHR0cHM6Ly9hcmphZ2Fubmpma2ZpbGVzLmJsb2IuY29yZS53aW5kb3dzLm5ldC9tYXJrZG93bi10dXRvcmlhbC9zYW1wbGVfbWFya2Rvd24ubWQ7NA2",
      "content": "#### h4 example\r\n##### h5 example\r\n###### h6 example\r\nThis is an example of content underneath a header.\r\n",
      "title": "Project Documentation",
      "h2_subheader": "Headers",
      "h3_subheader": "h3 example",
      "ordinal_position": 4
    }
  ]
}

重點︰

  • 因為markdownHeaderDepth設定為h3,所以h4h5h6標頭被視為純文字,因此它們會出現在content欄位中。

  • 這裡的序數位置為 4。 此內容在總共22個內容區段中排第四位。

新增 select 參數,將結果限定為較少的欄位。 新增 filter 以進一步縮小搜尋範圍。

### Query the index
POST {{baseUrl}}/indexes/sample-markdown-index/docs/search?api-version=2025-09-01  HTTP/1.1
Content-Type: application/json
api-key: {{apiKey}}
  
{
  "search": "Markdown",
  "count": true,
  "select": "title, content, h2_subheader",
  "filter": "h2_subheader eq 'Conclusion'"
}
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: a6f9bd46-a064-4e28-818f-ea077618014b
elapsed-time: 35
Date: Fri, 25 Oct 2024 20:36:10 GMT
Connection: close

{
  "@odata.context": "https://<YOUR-SEARCH-SERVICE-NAME>.search.windows.net/indexes('sample-markdown-index')/$metadata#docs(*)",
  "@odata.count": 1,
  "value": [
    {
      "@search.score": 1.1029507,
      "content": "Markdown is a lightweight yet powerful tool for writing documentation. It supports a variety of formatting options while maintaining simplicity and readability.\r\n\r\nThank you for reviewing this example!",
      "title": "Project Documentation",
      "h2_subheader": "Conclusion"
    }
  ]
}

在篩選中,您也可以使用邏輯運算子 (and、or、not) 和比較運算子 (eq、ne、gt、lt、ge、le)。 字串比較需區分大小寫。 如需詳細資訊和範例,請參閱建立查詢

附註

$filter 參數只能在索引建立時標記為可篩選的欄位中使用。

重設並重新執行

索引器可以重設為清除執行歷程記錄,以允許完整重新執行。 下列 GET 要求適用於重設,然後接著重新執行。

### Reset the indexer
POST {{baseUrl}}/indexers/sample-markdown-indexer/reset?api-version=2025-09-01  HTTP/1.1
api-key: {{apiKey}}

### Run the indexer
POST {{baseUrl}}/indexers/sample-markdown-indexer/run?api-version=2025-09-01  HTTP/1.1
api-key: {{apiKey}}

### Check indexer status 
GET {{baseUrl}}/indexers/sample-markdown-indexer/status?api-version=2025-09-01  HTTP/1.1
api-key: {{apiKey}}

清除資源

如果您使用自己的訂用帳戶,當專案結束時,建議您移除不再需要的資源。 讓資源繼續執行可能會產生費用。 您可以個別刪除資源,或刪除資源群組以刪除整組資源。

您可以使用 Azure 入口網站 來移除索引、索引器和資料來源。

下一步

現在您已熟悉 Azure Blob 索引編製的基本概念,請進一步瞭解 Azure 記憶體中 Markdown Blob 的索引器設定: