4.4 建立集合索引

為了更有效率地瀏覽大型文件集合,您可以根據集合中文件內的一或多個欄位建立索引。本節說明如何為集合建立索引。

建立索引

集合索引是提取集合中文件資料的虛擬資料行上的普通 MySQL 索引。因為 MySQL 無法直接為 JSON 值建立索引,為了能夠為集合建立索引,您必須提供 JSON 文件,其中指定索引要使用的文件欄位。您將定義索引的 JSON 文件當作 IndexDefinition 參數傳遞給 Collection.createIndex(name, IndexDefinition) 方法。此通用範例(針對不同的程式設計語言,實際語法可能會有所不同)示範如何根據 count 欄位建立強制整數類型索引

myCollection.createIndex("count", {fields:[{"field": "$.count", "type":"INT", required:true}]});

此範例示範如何根據文字欄位(在此情況下為郵遞區號)建立索引。針對文字欄位,您必須指定索引的前置長度,這是 MySQL Server 的要求

myCollection.createIndex("zip", {fields: [{field: "$.zip", type: "TEXT(10)"}]})

如需關於 IndexDefinition 格式和索引支援的欄位類型資訊,請參閱定義索引

如果已存在相同名稱的索引,或索引定義格式不正確,Collection.createIndex() 方法會失敗並產生錯誤。name 參數為必要參數,且必須是 SQL 陳述式 CREATE INDEX 接受的有效索引名稱。

若要移除現有索引,請使用 collection.dropIndex(string name) 方法。這會刪除具有傳入名稱的索引,且如果指定的索引不存在,則作業會靜默成功。

集合的索引會儲存為虛擬資料行。若要驗證已建立的索引,請使用 SHOW INDEX 陳述式。例如,從 MySQL Shell 使用此 SQL

session.runSql('SHOW INDEX FROM mySchema.myCollection');

定義索引

若要根據集合中的文件建立索引,您需要建立 IndexDefinition JSON 文件。本節說明您可以在此類 JSON 文件中使用哪些有效的欄位來定義索引。

若要定義要為其建立索引的集合文件欄位,該欄位的類型在整個集合中必須是一致的。換句話說,類型必須一致。用於定義索引的 JSON 文件,例如 {fields: [{field: '$.username', type: 'TEXT'}]},可以包含下列內容

  • fields:至少一個 IndexField 物件的陣列,其中每個物件描述要包含在索引中的 JSON 文件欄位。

    單一 IndexField 描述包含下列欄位

    • field:字串,其中包含要建立索引的文件成員或欄位的完整文件路徑

    • type:字串,表示要將欄位對應至的其中一種支援的資料行類型(請參閱欄位資料類型)。針對數值類型,可選的 UNSIGNED 關鍵字可以接在後面。針對 TEXT 類型,您必須定義要考慮建立索引的長度(前置長度)。

    • required:可選的布林值,如果文件必須存在該欄位,則應設定為 true。除了 GEOJSON 之外,所有類型預設為 false,而 GEOJSON 預設為 true

    • options:可選的整數,用作解碼 GEOJSON 資料時的特殊選項旗標(如需詳細資訊,請參閱ST_GeomFromGeoJSON()的描述)。

    • srid:可選的整數,在解碼 GEOJSON 資料時用作 srid 值(如需詳細資訊,請參閱ST_GeomFromGeoJSON()的描述)。

    • array:可選的布林值,如果欄位包含陣列,則設定為 true。預設值為 false。如需詳細資訊,請參閱建立陣列欄位索引

      重要事項

      對於 MySQL 8.0.16 及更早的版本,索引中不支援 JSON 陣列的欄位;指定包含陣列資料的欄位不會從伺服器產生錯誤,但索引不會正常運作。

  • type:可選的字串,用於定義索引類型。值為 INDEXSPATIAL 其中之一。預設值為 INDEX,且可以省略。

IndexDefinitionIndexField JSON 文件中包含任何未在上述說明的其他欄位,都會導致 collection.createIndex() 失敗並產生錯誤。

如果未指定索引類型或設定為 INDEX,則建立的索引方式與發出 CREATE INDEX 的方式相同。如果索引類型設定為 SPATIAL,則建立的索引與發出帶有 SPATIAL 關鍵字的 CREATE INDEX 所建立的索引相同,請參閱SPATIAL 索引最佳化建立空間索引。例如

myCollection.createIndex('myIndex', //
{fields: [{field: '$.myGeoJsonField', type: 'GEOJSON', required: true}], type:'SPATIAL'})
重要事項

當使用 SPATIAL 類型的索引時,無法在 IndexField 項目中將 required 欄位設定為 false

以下範例示範如何根據多個欄位建立索引

myCollection.createIndex('myIndex', {fields: [{field: '$.myField', type: 'TEXT'}, //
{field: '$.myField2', type: 'TEXT(10)'}, {field: '$.myField3', type: 'INT'}]})

索引欄位的值會使用標準 MySQL 類型轉換(請參閱運算式評估中的類型轉換)從 JSON 轉換為 IndexField 描述中指定的類型,但 GEOJSON 類型除外,該類型使用 ST_GeomFromGeoJSON() 函數進行轉換。這表示當在 IndexField 描述中使用數值類型時,非數值的實際欄位值會轉換為 0。

IndexField 中的 optionssrid 欄位只有在 type 設定為 GEOJSON 時才能存在。如果存在,則在將 GEOJSON 資料轉換為 MySQL 原生 GEOMETRY 值時,會將它們用作 ST_GeomFromGeoJSON() 的參數。

欄位資料類型

文件欄位支援下列資料類型。在 type 欄位中使用類型名稱時,不區分大小寫。

索引陣列欄位

X DevAPI 支援根據陣列欄位建立索引,方法是在 IndexField 描述中將布林值 array 欄位設定為 true。例如,要在 emails 陣列欄位上建立索引:

collection.createIndex("emails_idx", //
    {fields: [{"field": "$.emails", "type":"CHAR(128)", "array": true}]});

以下限制適用於根據陣列建立索引:

  • 對於每個索引,只有一個索引欄位可以是 array

  • 可以建立陣列索引的資料類型