共用方式為


定義父子式索引編製的索引投影

對於包含區塊化檔的索引,索引投影會指定父子內容如何對應至搜尋索引中一對多索引的欄位。 透過索引投影,您可以將內容傳送至:

  • 單一索引,其中父字段會針對每個區塊重複,但索引的粒紋位於區塊層級。 RAG 教學 課程 是此方法的範例。

  • 兩個或多個索引,其中父索引具有與父文件相關的欄位,而子索引則以區塊來組織。 子索引是主要搜尋主體,但是當您想要擷取特定區塊的父欄位或獨立查詢時,父索引可用於 查閱 查詢。

大部分的實作都是以父字段為區塊組織的單一索引,例如文件檔名,針對每個區塊重複。 不過,如果這是您的需求,系統會設計為支持個別和多個子索引。 Azure AI 搜尋不支援索引聯結,因此您的應用程式程式代碼必須處理要使用的索引。

索引投影定義於 技能集中。 它負責協調將內容區塊傳送至搜尋索引的編製程式,以及與每個區塊相關聯的父內容。 它藉由提供更多選項來控制父子內容編製索引的方式,以改善原生數據區塊化的運作方式。

本文說明如何建立一對多索引編製索引的索引架構和索引器投影模式。

必要條件

技能集包含索引器投影,可塑造一對多索引的數據。 如果您的案例包含整合向量化,技能集也可以有其他技能,例如 AzureOpenAIEmbedding內嵌技能。

索引器處理的相依性

一對多索引相依於技能集和索引器型索引編製,其中包含下列四個元件:

  • 資料來源
  • 可搜尋內容的一或多個索引
  • 包含索引投影的技能集*
  • 索引器

您的數據可能來自任何支持的數據源,但假設內容夠大而您想要將其區塊化,而區塊化的原因是您正在實作RAG模式,以提供基礎數據給聊天模型。 或者,您正在實作向量搜尋,而且必須符合內嵌模型的較小輸入大小需求。

索引器將索引數據載入預先定義的索引。 如何定義架構,以及是否要使用一個或多個索引,是一對多索引案例中要做出的第一個決策。 下一節涵蓋索引設計。

建立一對多索引的索引

無論您是針對重複父值的區塊建立一個索引,還是針對父子欄位放置建立個別索引,用於搜尋的主要索引是針對數據區塊所設計。 它必須具有下列欄位:

  • 可唯一識別每個檔的檔索引鍵欄位。 它必須定義為具有分析器的型 Edm.Stringkeyword

  • 欄位,將每個區塊與其父系產生關聯。 它必須是 Edm.String 型別。 它不能是檔索引鍵字段,而且必須 filterable 設定為 true。 其稱為範例中的parent_id,並稱為 本文中的投影索引鍵值

  • 內容的其他欄位,例如文字或向量化區塊欄位。

建立技能集或執行索引器之前,搜尋服務上必須有索引。

包含父欄位和子欄位的單一索引架構

針對每個區塊重複父內容所設計的單一索引,是RAG和向量搜尋案例的主要模式。 透過索引投影,能夠讓正確的父內容與每個區塊產生關聯。

下列架構是符合索引投影需求的範例。 在此範例中,父欄位是parent_id和標題。 子欄位是向量和非向量向量區塊。 chunk_id是此索引的文件標識碼。 索引中每個區塊的parent_id和標題都會重複。

您可以使用 Azure 入口網站、REST API 或 Azure SDK 來建立索引

{
    "name": "my_consolidated_index",
    "fields": [
        {"name": "chunk_id", "type": "Edm.String", "key": true, "filterable": true, "analyzer": "keyword"},
        {"name": "parent_id", "type": "Edm.String", "filterable": true},
        {"name": "title", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "retrievable": true},
        {"name": "chunk", "type": "Edm.String","searchable": true,"retrievable": true},
        {"name": "chunk_vector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": false, "stored": false, "dimensions": 1536, "vectorSearchProfile": "hnsw"}
    ],
    "vectorSearch": {
        "algorithms": [{"name": "hsnw", "kind": "hnsw", "hnswParameters": {}}],
        "profiles": [{"name": "hsnw", "algorithm": "hnsw"}]
    }
}

將索引投影新增至技能集

索引投影是在技能集定義內定義,主要定義為 的 selectors陣列,其中每個選取器都會對應至搜尋服務上的不同目標索引。 本節以內容語法和範例開頭,後面接著 參數參考

選擇各種 API 語法的索引標籤。 目前沒有入口網站支援設定投影,除了編輯技能集 JSON 定義之外。 請參閱 JSON 的 REST 範例。

索引投影已正式推出。 我們建議最新的穩定 API:

以下是索引投影定義的範例承載,您可能用來投影文字分割技能個別頁面輸出,做為搜尋索引中自己的檔。

"indexProjections": {
    "selectors": [
        {
            "targetIndexName": "my_consolidated_index",
            "parentKeyFieldName": "parent_id",
            "sourceContext": "/document/pages/*",
            "mappings": [
                {
                    "name": "chunk",
                    "source": "/document/pages/*",
                    "sourceContext": null,
                    "inputs": []
                },
                {
                    "name": "chunk_vector",
                    "source": "/document/pages/*/chunk_vector",
                    "sourceContext": null,
                    "inputs": []
                },
                {
                    "name": "title",
                    "source": "/document/title",
                    "sourceContext": null,
                    "inputs": []
                }
            ]
        }
    ],
    "parameters": {
        "projectionMode": "skipIndexingParentDocuments"
    }
}

參數參考

索引投影參數 定義
selectors 主要搜尋主體的參數,通常是圍繞區塊設計的參數。
projectionMode 選擇性參數,提供索引器指示。 此參數 skipIndexingParentDocuments的唯一有效值為 ,而且當區塊索引是主要搜尋主體時,會使用這個值,而且您需要指定父字段是否要編製成區塊索引索引內的額外搜尋檔。 如果您未設定 skipIndexingParentDocuments,則會在索引中取得區塊為 Null 的額外搜尋檔,但只填入父字段。 例如,如果五份檔對索引貢獻 100 個區塊,則索引中的檔數目為 105。 建立的五個檔或父字段具有區塊 (子) 欄位的 Null,使其與索引中的大部分檔大不相同。 我們建議 projectionMode 將 設定為 skipIndexingParentDocument

選取器具有下列參數做為其定義的一部分。

選取器參數 定義
targetIndexName 要投影索引數據之索引的名稱。 它是具有重複父欄位的單一區塊索引,或者如果您使用 父子內容的個別索引,則為子索引
parentKeyFieldName 提供父檔索引鍵的功能變數名稱。
sourceContext 擴充批注,定義將數據對應至個別搜尋檔的數據粒度。 如需詳細資訊,請參閱技能內容和輸入註釋語言
mappings 擴充數據與搜尋索引中字段的對應陣列。 每個對應都包含:
name:搜尋索引中數據應該編製索引的功能變數名稱。
source:應該從中提取資料的擴充註釋路徑。

每個 mapping 也可以使用選用的 sourceContextinputs 欄位以遞迴方式定義資料,類似於知識存放區Shaper 技能。 視您的應用程式而定,這些參數可讓您將數據塑造成搜尋索引中類型的 Edm.ComplexType 欄位。 某些 LLM 不接受搜尋結果中的複雜類型,因此您使用的 LLM 會判斷複雜類型對應是否有用。

參數 mappings 很重要。 您必須明確對應子索引中的每個欄位,但檔索引鍵和父標識碼等標識符欄位除外。

這項需求與 Azure AI 搜尋中的其他欄位對應慣例形成鮮明對比。 對於某些數據源類型,索引器可以根據類似名稱或已知特性隱含地對應欄位(例如,Blob 索引器會使用唯一的元數據記憶體路徑作為預設檔索引鍵)。 不過,對於索引器投影,您必須在關聯性的「多」端明確指定每個字段對應。

請勿建立父索引鍵欄位的欄位對應。 這樣做會中斷變更追蹤和同步處理的數據重新整理。

處理父文件

既然您已看到數個模式進行一對多索引編製,讓我們比較每個選項的主要差異。 索引投影可有效地為每個執行技能集的「父」檔產生「子」檔。 您有數個選項可處理「父」檔。

  • 若要將父和子檔傳送至不同的索引,請將索引器定義的 設定 targetIndexName 為父索引,並將 索引投影選取器中的 設定 targetIndexName 為子索引。

  • 若要將父和子檔保留在相同的索引中,請將索引器和 targetIndexName 索引投影 targetIndexName 設定為相同的索引。

  • 若要避免建立父搜尋檔並確保索引只包含統一粒紋的子檔,請將索引器定義和選取器的 設定targetIndexName為相同的索引,但在 之後selectorsprojectionMode新增額外的 parameters 物件,並將索引鍵設定為 skipIndexingParentDocuments,如下所示:

    "indexProjections": {
        "selectors": [
            ...
        ],
        "parameters": {
            "projectionMode": "skipIndexingParentDocuments"
        }
    }
    

檢閱欄位對應

索引器與三種不同類型的欄位對應相關聯。 執行索引器之前,請先檢查字段對應,並知道何時要使用每個類型。

欄位對應 定義於索引器中,並用來將來源欄位對應至索引字段。 欄位對應用於從來源提升數據並傳入索引的數據路徑,而不需要中繼技能處理步驟。 一般而言,索引器可以自動對應具有相同名稱和類型的欄位。 只有在有差異時,才需要明確欄位對應。 在到目前為止所討論的一對多索引編製和模式中,您可能不需要字段對應。

輸出欄位對應 定義於索引器中,並用來將技能集所產生的擴充內容對應至主索引的欄位。 在本文中所涵蓋的一對多模式中,這是雙索引解決方案中的父索引。 在本文所示的範例中,父索引是疏鬆的,只有標題欄位,而且該欄位不會填入技能集處理的內容,因此我們不會輸出字段對應。

索引器投影欄位對應可用來將技能集產生的內容對應至子索引中的欄位。 如果子索引也包含父欄位(如合併索引解決方案所示),您應該為每個包含內容的欄位設定欄位對應,包括父層級標題欄位,假設您希望標題顯示在每個區塊化檔中。 如果您使用 個別的父索引和子索引,索引器投影應該只有子層級欄位的欄位對應。

注意

輸出字段對應和索引器投影字段對應都會接受擴充的檔樹狀目錄節點作為來源輸入。 瞭解如何指定每個節點的路徑,對於設定數據路徑至關重要。 若要深入了解路徑語法,請參閱 參考擴充節點 的路徑和 技能集定義 以取得範例。

執行索引子

建立數據源、索引和技能集之後,即可 建立並執行索引器。 此步驟會將管線放入執行中。

您可以在處理結束后查詢搜尋索引,以測試您的解決方案。

內容生命週期

根據基礎數據源,索引器通常可以提供進行中的變更追蹤和刪除偵測。 本節說明一對多索引的內容生命週期,因為它與數據重新整理有關。

對於提供變更追蹤和刪除偵測的數據源,索引器程式可以挑選源數據中的變更。 每次您執行索引子和技能集時,如果技能集或基礎來源資料變更,索引投影就會隨之更新。 索引子所挑選的任何變更都會透過擴充流程傳播到索引中的投影,以確保投影的資料是原始資料來源中內容的目前形式。 數據重新整理活動會在每個區塊的投影索引鍵值中擷取。 當基礎數據變更時,此值會更新。

注意

雖然您可以使用索引推送 API 手動編輯投影檔中的數據,但您應該避免這樣做。 在下一個管線調用上會覆寫索引的手動更新,假設源數據中的檔已更新,且數據源已啟用變更追蹤或刪除偵測。

更新的內容

如果您將新內容新增至數據源,則會在下一個索引器執行時,將新的區塊或子檔新增至索引。

如果您修改數據源中的現有內容,如果您使用的數據源支援變更追蹤和刪除偵測,則會以累加方式在搜尋索引中更新區塊。 針對 exammple,如果檔中的單字或句子變更,則會在下一個索引器執行時更新包含該單字或句子的目標索引中的區塊。 現有欄位不支援其他類型的更新,例如變更欄位類型和某些屬性。 如需允許更新的詳細資訊,請參閱 變更索引架構

某些數據源,例如 Azure 儲存體 根據時間戳,默認支援變更和刪除追蹤。 必須針對變更追蹤設定其他數據源,例如 OneLakeAzure SQLAzure Cosmos DB

已刪除的內容

如果來源內容已不存在(例如,如果文字縮短為較少區塊),則會刪除搜尋索引中的對應子檔。 剩餘的子文件也會更新其索引鍵以包含新的雜湊值,即使其內容未以其他方式變更也一樣。

如果已從資料來源中完全刪除父文件,則只有在資料來源定義上定義的 dataDeletionDetectionPolicy 偵測到刪除時,才會刪除對應的子文件。 如果您沒有設定 dataDeletionDetectionPolicy,而且需要從資料來源中刪除父文件,則若不再需要子文件,您應該手動將其刪除。

投影索引鍵值

為了確保更新和刪除內容的數據完整性,數據重新整理在一對多索引中會依賴 「多」端的投影索引鍵值 。 如果您使用整合向量化或 匯入和向量化數據精靈,投影索引鍵值是 parent_id 索引區塊或「多」端的欄位。

投影索引鍵值是索引器為每個檔產生的唯一標識碼。 它可確保唯一性,並允許變更和刪除追蹤正常運作。 此索引鍵包含下列區段:

  • 保證唯一性的隨機雜湊。 如果在後續的索引器上更新父檔,此哈希就會變更。
  • 父文件的索引鍵。
  • 擴充註釋路徑,可識別從中產生文件的內容。

例如,如果您將索引鍵值 「aa1b22c33」 的父檔分割成四個頁面,然後每個頁面都會透過索引投影投影做為自己的檔:

  • aa1b22c33
  • aa1b22c33_pages_0
  • aa1b22c33_pages_1
  • aa1b22c33_pages_2

如果在源數據中更新父檔,或許會產生更多區塊化頁面、隨機哈希變更、新增更多頁面,而且會更新每個區塊的內容,以符合源檔中的任何內容。

個別父子式索引的範例

本節示範個別父索引和子索引的範例。 這是一種不常見的模式,但您可能有使用此方法最符合的應用程式需求。 在此案例中,您會將父子內容投影成兩個不同的索引。

每個架構都有其特定粒紋的欄位,其中兩個 索引通用的父標識元字段可用於查閱查詢。 主要搜尋主體是子索引,但接著發出查閱查詢來擷取結果中每個相符專案的父字段。 Azure AI 搜尋不支援在查詢時聯結,因此您的應用程式程式代碼或協調流程層需要合併或定序可傳遞至應用程式或進程的結果。

父索引具有parent_id欄位和標題。 parent_id是檔索引鍵。 除非您想要在父檔層級向量化欄位,否則不需要向量搜尋組態。

{
    "name": "my-parent-index",
    "fields": [

        {"name": "parent_id", "type": "Edm.String", "filterable": true},
        {"name": "title", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "retrievable": true},
    ]
}

子索引具有區塊欄位,加上parent_id欄位。 如果您使用整合式向量化、評分配置檔、語意排名器或分析器,您會在子索引中設定這些專案。

{
    "name": "my-child-index",
    "fields": [
        {"name": "chunk_id", "type": "Edm.String", "key": true, "filterable": true, "analyzer": "keyword"},
        {"name": "parent_id", "type": "Edm.String", "filterable": true},
         {"name": "chunk", "type": "Edm.String","searchable": true,"retrievable": true},
        {"name": "chunk_vector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": false, "stored": false, "dimensions": 1536, "vectorSearchProfile": "hnsw"}
    ],
    "vectorSearch": {
        "algorithms": [{"name": "hsnw", "kind": "hnsw", "hnswParameters": {}}],
        "profiles": [{"name": "hsnw", "algorithm": "hnsw"}]
    },
    "scoringProfiles": [],
    "semanticConfiguration": [],
    "analyzers": []
}

以下是索引投影定義的範例,指定索引器應該用來編製索引內容的數據路徑。 它會在索引投影定義中指定子索引名稱,並指定每個子或區塊層級欄位的對應。 這是指定子索引名稱的唯一位置。

"indexProjections": {
    "selectors": [
        {
            "targetIndexName": "my-child-index",
            "parentKeyFieldName": "parent_id",
            "sourceContext": "/document/pages/*",
            "mappings": [
                {
                    "name": "chunk",
                    "source": "/document/pages/*",
                    "sourceContext": null,
                    "inputs": []
                },
                {
                    "name": "chunk_vector",
                    "source": "/document/pages/*/chunk_vector",
                    "sourceContext": null,
                    "inputs": []
                }
            ]
        }
    ]
}

索引器定義會指定管線的元件。 在索引器定義中,要提供的索引名稱是父索引。 如果您需要父層級欄位的欄位對應,請在 outputFieldMappings 中定義它們。 對於使用個別索引的一對多索引,索引器定義看起來可能如下列範例所示。

{
  "name": "my-indexer",
  "dataSourceName": "my-ds",
  "targetIndexName": "my-parent-index",
  "skillsetName" : "my-skillset"
  "parameters": { },
  "fieldMappings": (optional) Maps fields in the underlying data source to fields in an index,
  "outputFieldMappings" : (required) Maps skill outputs to fields in an index,
}

後續步驟

數據區塊化和一對多索引是 Azure AI 搜尋中 RAG 模式的一部分。 請繼續進行下列教學課程和程式碼範例,以深入瞭解。