全部產品
Search
文件中心

Tablestore:數組和巢狀型別

更新時間:Nov 16, 2024

多元索引除了提供Long、Double、Boolean、Keyword、Text、Date、GeoPoint、Vector等基本類型外,還提供了數群組類型和巢狀型別兩種特殊類型。數群組類型適用於儲存一系列相同類型的資料,巢狀型別適用於儲存具有層級結構的資料,類似於JSON。

數群組類型

重要
  • 數群組類型僅是多元索引中的概念,資料表中尚未支援數組。

  • 向量Vector類型暫時不支援數組。

數群組類型屬於附加類型,可以附加在Long、Double、Boolean、Keyword、Text、Date、Geopoint等基本類型之上。例如Long類型+數組後,即為長整型數組,該欄位中可以包括多個長整型數字,查詢資料時其中任何一個匹配都可以返回該行資料。資料類型適用於儲存一系列相同類型的資料。

數組格式

多元索引的基本類型數組格式請參見下表。

數群組類型

說明

Long Array

長整型的數組形式,格式為"[1000, 4, 5555]"

Double Array

浮點數的數組形式,格式為"[3.1415926, 0.99]"

Boolean Array

布爾值的數組形式,格式為"[true, false]"

Keyword Array

字串的數組形式,格式為JSON Array,例如"[\"杭州\", \"西安\"]"

Text Array

文本的數組形式,格式為JSON Array,例如"[\"杭州\", \"西安\"]"

對於Text類型,一般無需使用數組形式。

Date Array

日期的數組形式。如果日期類型為整型,則格式為"[1218197720123, 1712850436000]";如果日期類型為字串,則格式為"[\"2024-04-11 23:47:16.854775807\", \"2024-06-11 23:47:16.854775807\"]"

Geopoint Array

地理位置點的數組形式,格式為"[\"34.2, 43.0\", \"21.4, 45.2\"]"

使用說明

對於多元索引中數群組類型的欄位,在資料表中必須為String類型,且對應的多元索引中的類型必須為相應的類型,例如Long、Double等。如果欄位price是Double Array數群組類型,則在資料表中price必須為String類型,在對應的多元索引中的類型必須為Double類型,且附加isArray=true屬性。

巢狀型別

巢狀型別(Nested)代表嵌套文件類型。嵌套文檔是指對於一行資料(文檔)可以包含多個子行(子文檔),多個子行儲存在一個巢狀型別欄位中。巢狀型別適用於儲存具有層級結構的資料。

對於巢狀型別欄位,需要指定其子行的結構,即子行中包含哪些欄位以及每個欄位的屬性。巢狀型別也是類似數組的多值結構,但是更接近JSON類型。

嵌套格式

根據資料的層級結構不同,巢狀型別包括單層級巢狀型別和多層級巢狀型別。具體說明請參見下表。

巢狀型別

說明

單層級巢狀型別

在一個資料結構中只包含一層其他資料結構,結構相對簡單,能表示一定的層次關係。單層級巢狀型別適用於不需要過多層級但需要一定層級結構的情境。樣本如下:

[
    {
        "tagName": "tag1",
        "score": 0.8
    },
    {
        "tagName": "tag2",
        "score": 0.2
    }
]

多層級巢狀型別

在一個資料結構中包含了多層嵌套的其他資料結構,具有更複雜的層次關係。多層級巢狀型別適用於需要表示豐富層次、高度模組化或高度組織化的資料模型。樣本如下:

[
    {
        "name": "張三",
        "age": 20,
        "phone": "1390000****",
        "address": [
            {
                "province": "浙江省",
                "city": "杭州市",
                "street": "陽光大道幸福小區1201號"
            }
        ]
    }
]

使用說明

對於多元索引中巢狀型別的欄位,在資料表中必須為String類型,且對應的多元索引中的類型必須為巢狀型別。巢狀型別欄位只能使用巢狀型別查詢功能進行資料查詢。

在寫入資料到資料表時,多元索引巢狀型別欄位對應資料表欄位的寫入格式必須為JSON對象的數組格式,例如[{"tagName":"tag1", "score":0.8,"time": 1730690237000 }, {"tagName":"tag2", "score":0.2,"time": 1730691557000}]

重要

即使只有一個子行,也必須按照JSON數組的格式構造字串。

使用樣本

單層級巢狀型別樣本

單層級巢狀型別支援通過控制台或者SDK進行建立。

以Java代碼為例介紹建立單層級巢狀型別。樣本中巢狀型別欄位的名稱為tags,子行中包含三個欄位,如下圖所示。

image

  • 一個欄位名稱為tagName,類型為字串類型(Keyword)。

  • 一個欄位名稱為score,類型為浮點數(Double)。

  • 一個欄位名稱為time,類型為日期時間類型(Date),取值單位為毫秒時間戳記。

寫入資料表時的資料範例為[{"tagName":"tag1", "score":0.8,"time": 1730690237000 }, {"tagName":"tag2", "score":0.2,"time": 1730691557000}]

//構造子行的FieldSchema。
List<FieldSchema> subFieldSchemas = new ArrayList<FieldSchema>();
subFieldSchemas.add(new FieldSchema("tagName", FieldType.KEYWORD)
    .setIndex(true).setEnableSortAndAgg(true));
subFieldSchemas.add(new FieldSchema("score", FieldType.DOUBLE)
    .setIndex(true).setEnableSortAndAgg(true));
subFieldSchemas.add(new FieldSchema("time", FieldType.DATE)
    .setDateFormats(Arrays.asList("epoch_millis")));

//將子行的FieldSchema設定到巢狀型別欄位的subfieldSchemas中。
FieldSchema nestedFieldSchema = new FieldSchema("tags", FieldType.NESTED)
    .setSubFieldSchemas(subFieldSchemas);

多層級巢狀型別樣本

多層級巢狀型別只能通過SDK進行建立。

以Java範例程式碼為例介紹建立多層級巢狀型別。樣本中巢狀型別欄位的名稱為user,子行中包含四個基礎類型欄位和一個巢狀型別欄位。

  • 一個欄位名稱為name,類型為字串類型(Keyword)。

  • 一個欄位名稱為age,類型為長整型(Long)。

  • 一個欄位名稱為birth,類型為日期時間類型(Date),取值為日期格式。

  • 一個欄位名稱為phone,類型為字串類型(Keyword)。

  • 一個巢狀型別欄位的名稱為address,子行中包含的三個欄位名稱分別為province、city和street,類型均為字串類型(Keyword)。

寫入資料表時的資料範例為[ {"name":"張三","age":20,"brith":"2014-10-10 12:00:00.000","phone":"1390000****","address":[{"province":"浙江省","city":"杭州市","street":"陽光大道幸福小區1201號"}]}]

//構造巢狀型別欄位address的子行FieldSchema,子行中包含三個欄位。查詢子行中欄位的資料時,子行中欄位的路徑為user.address。
List<FieldSchema> addressSubFiledSchemas = new ArrayList<>();
addressSubFiledSchemas.add(new FieldSchema("province",FieldType.KEYWORD));
addressSubFiledSchemas.add(new FieldSchema("city",FieldType.KEYWORD));
addressSubFiledSchemas.add(new FieldSchema("street",FieldType.KEYWORD));

//構造巢狀型別欄位user的子行FieldSchema,子行中包含三個基礎類型欄位和一個巢狀型別欄位address。查詢子行中欄位的資料時,子行中欄位的路徑為user。
List<FieldSchema> subFieldSchemas = new ArrayList<>();
subFieldSchemas.add(new FieldSchema("name",FieldType.KEYWORD));
subFieldSchemas.add(new FieldSchema("age",FieldType.LONG));
subFieldSchemas.add(new FieldSchema("birth",FieldType.DATE).setDateFormats(Arrays.asList("yyyy-MM-dd HH:mm:ss.SSS")));
subFieldSchemas.add(new FieldSchema("phone",FieldType.KEYWORD));
subFieldSchemas.add(new FieldSchema("address",FieldType.NESTED).setSubFieldSchemas(addressSubFiledSchemas));

//將巢狀型別欄位user的子行FieldSchema設定到巢狀型別欄位的subfieldSchemas中。
List<FieldSchema> fieldSchemas = new ArrayList<>();
fieldSchemas.add(new FieldSchema("user",FieldType.NESTED).setSubFieldSchemas(subFieldSchemas));

巢狀型別的局限性

  • 由於含有巢狀型別欄位的多元索引不支援索引預排序(IndexSort),而索引預排序功能在很多情境下可以帶來很大效能提升。

  • 如果使用含有巢狀型別欄位的多元索引查詢資料且需要翻頁,則必須在查詢條件中指定資料返回的排序方式,否則當符合查詢條件的資料未讀取完時,服務端不會返回nextToken。

  • 巢狀型別的查詢效能相比其他類型的查詢效能更低一些。

巢狀型別除了上述局限性外,和非巢狀型別支援的功能相同,支援所有的查詢類型、排序和統計彙總。

相關文檔