View a markdown version of this page

建立和搜尋向量索引 - Amazon DynamoDB

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

建立和搜尋向量索引

本節說明如何建立和管理向量索引、使用向量資料寫入項目,以及使用 SearchVectors API 執行相似性搜尋。

開始之前

在使用向量索引之前,請確認下列事項:

  • 您的資料表使用隨需容量模式 (PAY_PER_REQUEST)。佈建容量資料表不支援向量索引。

  • 您的 AWS Identity and Access Management (IAM) 身分具有建立向量索引的 dynamodb:CreateTabledynamodb:UpdateTable許可。

  • 您的 IAM 身分具有向量索引資源執行搜尋的dynamodb:SearchVectors許可。資源 ARN 格式為 arn:aws:dynamodb:region:account-id:table/table-name/index/index-name

SearchVectors 端點

SearchVectors 請求使用專用向量搜尋端點,這與您用來建立和管理向量索引的標準 DynamoDB 端點不同 (例如,使用 CreateTableUpdateTableDescribeTable)。 AWS SDKs 和 會自動將SearchVectors請求 AWS CLI 路由到正確的端點。您不需要在應用程式程式碼中設定或覆寫端點。

如果您要建置自訂 HTTP 用戶端,在沒有 AWS SDK 的情況下直接呼叫 DynamoDB API,請使用下列其中一個向量搜尋端點,視需要取代 account-idregion

  • account-id.search-ddb.region.amazonaws.com — 以帳戶為基礎的端點。

  • search-dynamodb.region.api.aws — 雙堆疊端點,與 IPv4 和 IPv6 相容。

產生向量內嵌

DynamoDB 會儲存和搜尋向量內嵌,但不會產生它們。您可以使用內嵌模型產生內嵌,例如 Amazon Bedrock Titan 文字內嵌或 Cohere 內嵌模型,或您操作的任何內嵌模型。然後,將產生的向量存放在 DynamoDB 項目中,並將查詢向量傳遞給 SearchVectors

查詢向量和預存向量必須使用相同的模型

您傳遞至 的查詢向量SearchVectors和存放在您項目中的向量必須由相同的內嵌模型產生,且必須具有與向量索引相同的維度。混合模型或使用與建立索引不同的維度進行查詢,會產生無意義的結果或驗證錯誤。

典型的流程為:

  1. 將您的來源內容 (例如產品描述) 傳送至內嵌模型並接收向量。

  2. 將該向量存放在 DynamoDB 項目中,以向量索引 (VectorAttribute) 命名的屬性中,做為數字 (L) 的清單 ()N

  3. 在查詢時間,使用相同的模型從搜尋文字產生向量,並將其傳遞為 SearchVector

在建立索引之前選擇您的內嵌模型

在建立向量索引之前選擇內嵌模型,因為模型會決定維度數目。常見的內嵌模型會產生 384、768、1024、1536 或 3072 維度。DynamoDB 最多支援 4,096 個維度。請參閱 要求與限制

您選擇的距離函數會與您的模型產生內嵌的方式互動。 會COSINE比較方向並忽略大小,因此它可與內嵌搭配使用,無論其是否標準化。 DOT_PRODUCT 對大小敏感:如果您的內嵌未標準化為單位長度,則無論方向為何,較大的向量都會獲得更高的分數。如果您使用 DOT_PRODUCT且想要以方向為基礎的相似性,請將內嵌標準化為單位長度,然後再存放。請參閱 距離函數如何排名結果

建立向量索引

您可以在建立新資料表時建立向量索引,或將向量索引新增至現有資料表。

使用向量索引建立資料表

使用 CreateTable API 搭配 VectorIndexes 參數來建立具有向量索引的資料表。下列 AWS CLI 範例會建立具有名為 之向量索引的Products資料表ProductEmbeddingIndex

aws dynamodb create-table \ --table-name Products \ --attribute-definitions AttributeName=ProductId,AttributeType=S \ AttributeName=Category,AttributeType=S \ AttributeName=Brand,AttributeType=S \ --key-schema AttributeName=ProductId,KeyType=HASH \ --billing-mode PAY_PER_REQUEST \ --vector-indexes \ "[ { \"IndexName\": \"ProductEmbeddingIndex\", \"VectorAttribute\": {\"AttributeName\": \"Embedding\"}, \"SearchSchema\": [{\"AttributeName\":\"Category\",\"SearchSchemaElementType\":\"HASH\"}, {\"AttributeName\":\"Brand\",\"SearchSchemaElementType\":\"INLINE_FILTER\"}], \"Projection\": {\"ProjectionType\": \"ALL\"}, \"Dimensions\": 1536, \"DistanceFunction\": \"COSINE\" } ]"

在此範例中:

  • VectorAttribute 指定 Embedding為包含向量資料的屬性。

  • SearchSchemaCategory定義為向量索引分割區索引鍵 (HASH),依類別分割索引以進行擴展。它還將 Brand定義為 INLINE_FILTER,可讓您在儲存層依品牌篩選搜尋結果。由於 SearchSchema 中同時參考BrandCategory和 ,因此它們也必須在 中宣告AttributeDefinitions,因此全域次要索引的金鑰屬性宣告方式相同。

  • Dimensions 設定為 1536,符合常見內嵌模型的輸出。

  • DistanceFunction 設定為 COSINE,其中分數越低表示相似度越高。

將向量索引新增至現有資料表

使用 UpdateTable API 搭配 VectorIndexUpdates 參數,將向量索引新增至現有資料表。此範例會將名為 的第二個獨立索引ProductEmbeddingIndexV2新增至相同的Products資料表。

aws dynamodb update-table \ --table-name Products \ --vector-index-updates \ "[ { \"Create\": { \"IndexName\": \"ProductEmbeddingIndexV2\", \"VectorAttribute\": {\"AttributeName\": \"Embedding\"}, \"Projection\": {\"ProjectionType\": \"ALL\"}, \"Dimensions\": 1536, \"DistanceFunction\": \"EUCLIDEAN\" } } ]"

當您將向量索引新增至現有資料表時,DynamoDB Backfilling 會透過DescribeTable回應中的兩個欄位報告索引進度: IndexStatus值和單獨的布林值。

  1. IndexStatus is CREATING — DynamoDB 正在設定索引基礎設施。

  2. IndexStatus ACTIVEBackfilling設定為 true:DynamoDB 正在將索引填入基礎資料表中的現有資料。在此階段,基底資料表的新寫入也會複寫到索引。當向量索引回填時, SearchVectors會傳回錯誤。等到 Backfilling 開始搜尋false

  3. IndexStatus ACTIVEBackfilling設定為 false(或不存在) — 索引已完全填入並準備好進行搜尋操作。

您無法在索引回填時搜尋

SearchVectors 在向量索引回填時傳回錯誤。使用 DescribeTable同時檢查 IndexStatusBackfilling旗標,並等到 IndexStatusACTIVEBackfilling 為您搜尋false之前。沒有BACKFILLING索引狀態值。

使用向量資料寫入項目

您可以使用標準 DynamoDB 寫入 APIs (PutItemUpdateItemBatchWriteItem、) 搭配向量資料寫入項目TransactWriteItems。將向量內嵌儲存為數字清單 (L 類型包含N元素)。

由於向量包含許多值,請將項目儲存至 等檔案item.json,然後將檔案傳遞至 AWS CLI。

{ "ProductId": { "S": "prod-123" }, "Category": { "S": "Electronics" }, "Title": { "S": "Wireless Headphones" }, "Embedding": { "L": [ { "N": "0.1234" }, { "N": "-0.5678" }, { "N": "0.9012" }, ... ] } }
aws dynamodb put-item \ --table-name Products \ --item file://item.json
向量長度必須符合索引維度

此處顯示的Embedding向量為縮寫。在 中item.json,它必須包含 1,536 個值,以符合Dimensions您在 上設定的 ProductEmbeddingIndex。寫入維度不正確的向量會遭到拒絕。

當您將項目寫入具有向量索引的資料表時,DynamoDB 會驗證向量資料。下表說明驗證行為。

條件 Behavior (行為)
向量屬性的維度數目錯誤 寫入遭拒。
缺少向量索引分割區索引鍵屬性 在基礎資料表上寫入成功,但項目不會複寫到向量索引。
向量索引分割區索引鍵屬性類型與索引結構描述不相符 寫入遭拒。
缺少內嵌篩選條件屬性 寫入成功,且項目會複寫至向量索引。
向量值的精確度高於 32 位元浮點 (f32) 寫入成功。值會依原樣存放在基底資料表中,但在複寫至向量索引時失去精確度。
從項目中刪除向量屬性 向量索引中的對應項目會被刪除。
缺少分割區索引鍵會導致無提示取消索引

如果您的向量索引在 SearchSchema 中定義分割區索引鍵,而且您撰寫的項目沒有該屬性 (或使用 將其移除UpdateItem),則寫入會在基礎資料表上成功,但該項目會無提示地從向量索引中排除。即使基礎資料表項目及其向量內嵌仍然存在,它也不會出現在SearchVectors結果中。確定您要搜尋的每個項目都包含向量索引分割區索引鍵屬性。

過時的內嵌會產生不正確的結果

DynamoDB 不會為您重新計算內嵌。如果您變更產生內嵌的來源內容 (例如,編輯產品描述),儲存的向量不會自動更新。您必須使用內嵌模型重新產生內嵌,並將新的向量寫入項目。否則,向量索引會根據舊的過時向量繼續傳回結果,這會無提示地產生不正確的相符項目。

使用 SearchVectors 搜尋

使用 SearchVectors API 尋找向量索引中最類似查詢向量的項目。結果會依相關性排序,最相似的項目優先。搜尋結果最終一致:寫入或更新向量之間可能會出現短暫的延遲,且顯示在搜尋結果中。如需詳細資訊,請參閱持續寫入同步

基本搜尋

下列範例會搜尋ProductEmbeddingIndex索引中 10 個最相似的項目。由於此索引在其 SearchSchema 中已定義向量索引分割區索引鍵 (Category),因此 SearchConditionExpression必須包含向量索引分割區索引鍵值。

將查詢向量儲存到檔案,例如 query-vector.json,做為數值的純 JSON 陣列。

[ { "N": "0.1234" }, { "N": "-0.5678" }, { "N": "0.9012" }, ... ]
aws dynamodb search-vectors \ --table-name Products \ --index-name ProductEmbeddingIndex \ --search-vector file://query-vector.json \ --top-k 10 \ --search-condition-expression "Category = :cat" \ --expression-attribute-values "{\":cat\": {\"S\": \"Electronics\"}}"

回應包含SearchResults陣列。每個元素都包含相符項目ItemScore,指出項目與查詢向量的相似度。

{ "SearchResults": [ { "Item": { "ProductId": { "S": "prod-456" }, "Category": { "S": "Electronics" }, "Title": { "S": "Bluetooth Speaker" } }, "Score": 0.0023 }, { "Item": { "ProductId": { "S": "prod-789" }, "Category": { "S": "Electronics" }, "Title": { "S": "Noise Cancelling Earbuds" } }, "Score": 0.0145 } ] }
根據預設,向量屬性會從結果中排除

根據預設,來自 的結果SearchVectors不包含向量屬性 (內嵌)。向量資料很大,通常在回應中不需要它。結果包含其他投影屬性和 Score值。若要包含向量屬性,請使用 請求它ProjectionExpression。如需詳細資訊,請參閱使用 ProjectionExpression

SearchVector 是純清單,不是 DynamoDB L 類型

SearchVector 請求參數是數字物件的純 JSON 陣列 ([{"N": "0.1234"}, ...])。請勿在 DynamoDB L類型中包裝它,就像在項目屬性中存放向量一樣。L 包裝函式只會在項目屬性中寫入或讀取向量資料時使用。

的意義Score取決於您在建立索引時選擇的距離函數。對於 COSINEEUCLIDEAN,分數越低表示相似度越高。對於 DOT_PRODUCT,分數越高表示相似性越大。

使用 SearchConditionExpression 篩選

使用 根據向量索引分割區索引鍵和 SearchSchema 中定義的內嵌篩選條件屬性來SearchConditionExpression篩選搜尋結果。此表達式使用與其他 DynamoDB 表達式參數相同的語法。

下列範例會使用內嵌篩選條件搜尋Electronics類別 (向量索引分割區索引鍵) Brand 中的項目。

aws dynamodb search-vectors \ --table-name Products \ --index-name ProductEmbeddingIndex \ --search-vector file://query-vector.json \ --top-k 10 \ --search-condition-expression "Category = :cat AND Brand = :brand" \ --expression-attribute-values "{\":cat\": {\"S\": \"Electronics\"}, \":brand\": {\"S\": \"Acme\"}}"

如果您的向量索引具有 SearchSchema 中定義的分割區索引鍵,則必須將其包含在 中SearchConditionExpression。內嵌篩選條件屬性是選用的。

在 中SearchConditionExpression,向量索引分割區索引鍵和內嵌篩選條件屬性都支援等式運算子 (=)。尚未提供比較、範圍和設定成員運算子 (<><<=>>=IN)。

此篩選可讓您將相似性搜尋範圍限定為資料子集,這是多租戶和擷取增強生成 (RAG) 應用程式的常見需求。例如,若要尋找類似查詢但僅在一個租用戶內的文件,請在 SearchSchema 中將租用戶屬性定義為向量索引分割區索引鍵 (HASH),並在每次搜尋中傳遞其值。這會將結果隔離到該租用戶。它也會改善效能,因為搜尋只會檢查相關資料。將內嵌篩選條件屬性用於您想要在路由分割區中套用的其他相等性限制,例如文件類型或狀態。

分割區索引鍵範圍不是安全界限

使用分割區索引鍵將搜尋範圍限定為單一租用戶,是一種資料本機性和效能最佳化,而不是存取控制機制。擁有索引dynamodb:SearchVectors許可的任何主體都可以搜尋任何分割區索引鍵值。由於 等精細存取控制 (FGAC) 條件金鑰dynamodb:LeadingKeys不適用於 SearchVectors,因此您無法限制存取 IAM 政策層級的個別分割區金鑰值。如果您的工作負載需要在資料層進行嚴格的租用戶隔離,請為每個租用戶使用具有不同 IAM 授權的個別資料表或索引。

使用 ProjectionExpression

ProjectionExpression 使用 僅傳回搜尋結果中的特定屬性。當您不需要所有投影的屬性時,這可以減少回應大小。由於 在其 SearchSchema 中ProductEmbeddingIndex定義向量索引分割區索引鍵 (Category),因此此範例仍會包含 中的向量索引分割區索引鍵值SearchConditionExpression

aws dynamodb search-vectors \ --table-name Products \ --index-name ProductEmbeddingIndex \ --search-vector file://query-vector.json \ --top-k 5 \ --search-condition-expression "Category = :cat" \ --expression-attribute-values "{\":cat\": {\"S\": \"Electronics\"}}" \ --projection-expression "ProductId, Title"
只能傳回投影的屬性

您只能傳回投影到向量索引中的屬性。無法傳回不在索引投影中的屬性SearchVectors

刪除向量索引

使用 UpdateTable API 搭配 VectorIndexUpdates 參數來刪除向量索引。

aws dynamodb update-table \ --table-name Products \ --vector-index-updates \ "[ {\"Delete\": {\"IndexName\": \"ProductEmbeddingIndex\"}} ]"

當您刪除向量索引時,DynamoDB 會移除索引及其所有資料。此操作不會影響基底資料表或其項目。