すべてのプロダクト
Search
ドキュメントセンター

Tablestore:配列データ型とネストデータ型

最終更新日:Feb 15, 2025

検索インデックスは、Long、Double、Boolean、Keyword、Text、Date、Geopoint、Vector などの基本データ型をサポートしています。また、配列データ型とネストデータ型もサポートしています。配列データ型は、同じ型のデータのコレクションを格納するのに適しています。ネストデータ型は JSON データ型に似ており、階層構造を持つデータを格納するのに適しています。

配列データ型

重要
  • 配列データ型は検索インデックスでのみ使用できます。データテーブルは配列データ型をサポートしていません。

  • 配列データ型は、配列以外のデータ型と同じ方法で使用できます。配列フィールドを使用してデータをクエリすると、配列内の少なくとも 1 つの値が条件を満たしている場合、データの行が返されます。

  • ベクトルデータ型は配列で使用できません。

配列データ型は複合データ型であり、Long、Double、Boolean、Keyword、Text、Date、Geopoint などの基本データ型と組み合わせて、複雑なデータ構造を構築できます。たとえば、Long データ型と配列データ型の組み合わせを使用して、long 配列を構築します。 long 配列には複数の long 整数を格納できます。配列データ型は、同じ型のデータのコレクションを格納するのに適しています。

配列の形式

次の表は、検索インデックスにおける配列データ型と基本データ型の組み合わせについて説明しています。

組み合わせ

説明

Long 配列

long 整数の配列。例: "[1000, 4, 5555]"

Double 配列

浮動小数点数の配列。例: "[3.1415926, 0.99]"

Boolean 配列

ブール値の配列。例: "[true, false]"

Keyword 配列

文字列の配列。keyword 配列は JSON 配列です。例: "[\"Hangzhou\", \"Xi'an\"]"

Text 配列

テキストの配列。text 配列は JSON 配列です。例: "[\"Hangzhou\", \"Xi'an\"]"

Text 配列はあまり使用されません。

Date 配列

日付データの配列。Integer 型の日付データの例: "[1218197720123, 1712850436000]"。String 型の日付データの例: "[\"2024-04-11 23:47:16.854775807\", \"2024-06-11 23:47:16.854775807\"]"

Geopoint 配列

緯度と経度の座標ペアの配列。例: "[\"34.2, 43.0\", \"21.4, 45.2\"]"

使用上の注意

検索インデックスのフィールドのデータ型が、Long や Double などの配列データ型と基本データ型の組み合わせである場合、検索インデックスが作成されるデータテーブルのフィールドは String 型である必要があり、検索インデックスのフィールドは対応する基本データ型である必要があります。

たとえば、price フィールドは Double 配列型です。データテーブルの price フィールドの値は String 型、検索インデックスの price フィールドの値は Double 型である必要があり、isArray=true を指定する必要があります。

次の表は、array_search_table という名前のデータテーブルのサンプルデータを示しています。

データテーブルは、String 型の pk プライマリキー列、String 型の col_keyword_array 属性列、および String 型の col_long_array 属性列で構成されています。

pk

col_keyword_array

col_long_array

03#server#07

["Development environment", "Test environment", "Physical server", "Linux" ]

[2020, 2023]

4c#server#ae

["Production environment", "Cloud server", "Linux" ]

[2021, 2024]

  1. 検索インデックスを作成します。

    この例では、array_query_table_index という名前の検索インデックスを作成します。検索インデックスには、配列データ型の次のフィールドが含まれています。Keyword データ型の要素を格納する col_keyword_array フィールドと、Long データ型の要素を格納する col_long_array フィールドです。

    image

  2. 検索インデックスを使用して、配列データ型のデータをクエリします。

    次の Java コードのサンプルは、検索インデックスを使用して配列データ型のデータをクエリする方法の例を示しています。この例では、col_keyword_array 列の値に「Cloud server」と完全に一致する要素が含まれ、col_long_array 列の値に 2024 と等しい要素が含まれる行が、クエリ条件を満たしています。

    説明

    SQL ステートメントを実行して、検索インデックス内の配列データ型のデータをクエリできます。詳細については、「SQL ステートメントを実行して検索インデックスを使用してデータをクエリする」をご参照ください。

    private static void query(SyncClient client) {
        // 条件 1: col_keyword_array 列の値に「Cloud server」と完全に一致する要素が含まれている。
        TermQuery keywordTermQuery = new TermQuery(); // クエリタイプを TermQuery に設定します。
        keywordTermQuery.setFieldName("col_keyword_array"); // 一致させたい列の名前を指定します。
        keywordTermQuery.setTerm(ColumnValue.fromString("Cloud server")); // フィールドと一致させるために使用する値を指定します。
        
        // 条件 2: col_long_array 列の値に 2024 と等しい要素が含まれている。
        TermQuery longTermQuery = new TermQuery(); // クエリタイプを TermQuery に設定します。
        longTermQuery.setFieldName("col_long_array"); // 一致させたい列の名前を指定します。
        longTermQuery.setTerm(ColumnValue.fromLong(2024l)); // フィールドと一致させるために使用する値を指定します。
        
        SearchQuery searchQuery = new SearchQuery();
        // クエリ結果が条件 1 と条件 2 を同時に満たすブールクエリを構築します。
        BoolQuery boolQuery = new BoolQuery();
        boolQuery.setMustQueries(Arrays.asList(keywordTermQuery, longTermQuery));
        searchQuery.setQuery(boolQuery);
        //searchQuery.setGetTotalCount(true); // 一致する行の総数が返されるように指定します。
        
        SearchRequest searchRequest = new SearchRequest("<TABLE_NAME>", "<SEARCH_INDEX_NAME>", searchQuery);
        // columnsToGet パラメーターを設定して、返す列を指定するか、すべての列を返すように指定できます。このパラメーターを設定しない場合、プライマリキー列のみが返されます。
        //SearchRequest.ColumnsToGet columnsToGet = new SearchRequest.ColumnsToGet();
        //columnsToGet.setReturnAll(true); // すべての列が返されるように指定します。
        //columnsToGet.setColumns(Arrays.asList("ColName1","ColName2")); // 返す列を指定します。
        //searchRequest.setColumnsToGet(columnsToGet);
        
        SearchResponse resp = client.search(searchRequest);
        //System.out.println("TotalCount: " + resp.getTotalCount()); // 返される行数ではなく、一致する行の総数が表示されるように指定します。
        System.out.println("Row: " + resp.getRows());
    }

ネストデータ型

ネスト型のデータはネストされたドキュメントです。ネストされたドキュメントは、データの行(ドキュメント)に複数の子行(子ドキュメント)が含まれている場合に使用されます。複数の子行はネストされたフィールドに格納されます。ネストデータ型は、階層構造を持つデータを格納するのに適しています。

ネストされたフィールドの子行のスキーマを指定する必要があります。スキーマには、子行のフィールドと各フィールドのプロパティが含まれている必要があります。ネストデータ型は、JSON データ型と同様に、複数の値を格納するために使用できます。

ネストの形式

ネストされたフィールドは、単一レベルと複数レベルのネストされたフィールドに分類されます。次の表で、2 つのタイプについて説明します。

タイプ

説明

単一レベルのネストされたフィールド

単一レベルのネストされたフィールドは、1 つのレベルのみを含む単純なデータ構造を持っています。単一レベルのネストされたフィールドは、複数レベルのデータ構造は必要ないが、階層構造が必要なシナリオに適しています。例:

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

複数レベルのネストされたフィールド

複数レベルのネストされたフィールドは、複数レベルを含む複雑なデータ構造を持っています。複数レベルのネストされたフィールドは、さまざまなレベルの編成されたデータを集中モジュールに格納するために複雑なデータ構造が必要なシナリオに適しています。例:

[
    {
        name:"John",
        "age": 20,
        "phone": "1390000****",
        "address": [
            {
                "province": "Zhejiang",
                "city": "Hangzhou",
                "street": "1201 Xingfu Community, Sunshine Avenue"
            }
        ]
    }
]

使用上の注意

検索インデックスのフィールドがネスト型の場合、検索インデックスが作成されるデータテーブルのフィールドは String 型である必要があり、検索インデックスのフィールドはネスト型である必要があります。ネスト型のフィールドをクエリするには、ネストクエリを実行する必要があります。

データテーブルのフィールドにデータを書き込み、そのフィールドがデータテーブル用に作成された検索インデックスのネストフィールドに対応している場合、データテーブルのフィールドが JSON 配列型であることを確認してください。例: [{"tagName":"tag1", "score":0.8,"time": 1730690237000 }, {"tagName":"tag2", "score":0.2,"time": 1730691557000}]

重要

フィールドに子行が 1 つしか含まれていないかどうかに関係なく、JSON 配列型の文字列をネストフィールドに書き込む必要があります。

単一レベルのネストされたフィールドの例

[Tablestore コンソール] または Tablestore SDK を使用して、単一レベルのネストされたフィールドを作成できます。

このセクションでは、Tablestore SDK for Java を使用して単一レベルのネストされたフィールドを作成する方法について説明します。この例では、tags という名前のネストされたフィールドを作成します。各子行には 3 つのフィールドが含まれています。次の図は詳細を示しています。

image

  • フィールド名: tagName。フィールドタイプ: Keyword。

  • フィールド名: score。フィールドタイプ: Double。

  • フィールド名: time。フィールドタイプ: Date。単位: ミリ秒。

データテーブルに書き込まれたサンプルデータ: [{"tagName":"tag1", "score":0.8,"time": 1730690237000 }, {"tagName":"tag2", "score":0.2,"time": 1730691557000}]

// 子行のフィールドのスキーマを作成します。
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")));

// ネストされたフィールドの subfieldSchemas の値として、子行用に作成されたスキーマを使用します。
FieldSchema nestedFieldSchema = new FieldSchema("tags", FieldType.NESTED)
    .setSubFieldSchemas(subFieldSchemas);

複数レベルのネストされたフィールドの例

Tablestore SDK を使用して、複数レベルのネストされたフィールドを作成できます。

このセクションでは、Tablestore SDK for Java を使用して複数レベルのネストされたフィールドを作成する方法について説明します。この例では、user という名前のネストされたフィールドを作成します。各子行には、異なる基本データ型の 4 つのフィールドと 1 つのネストされたフィールドが含まれています。

  • フィールド名: name。フィールドタイプ: Keyword。

  • フィールド名: age。フィールドタイプ: Long。

  • フィールド名: birth。フィールドタイプ: Date。フィールドの値は日付形式です。

  • フィールド名: phone。フィールドタイプ: Keyword。

  • ネストされたフィールド名: address。各子行のフィールド名: province、city、street。各子行のすべてのフィールドのデータ型: Keyword。

データテーブルに書き込まれたサンプルデータ: [ {"name":"John","age":20,"brith":"2014-10-10 12:00:00.000","phone":"1390000****","address":[{"province":"Zhejiang","city":"Hangzhou","street":"1201 Xingfu Community, Sunshine Avenue"}]}]

// address ネストされたフィールドの子行の 3 つのフィールドのスキーマを作成します。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 の各子行のスキーマを作成します。各子行には、異なる基本データ型の 3 つのフィールドと、address という名前の 1 つのネストされたフィールドが含まれています。ネストされたフィールド 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));

// ネストされたフィールドの subfieldSchemas の値として、ネストされたフィールド user の子行用に作成されたスキーマを使用します。
List<FieldSchema> fieldSchemas = new ArrayList<>();
fieldSchemas.add(new FieldSchema("user",FieldType.NESTED).setSubFieldSchemas(subFieldSchemas));

制限

  • ネストインデックスは、さまざまなシナリオでクエリパフォーマンスを向上させるために使用できる IndexSort 機能をサポートしていません。

  • ネストされたフィールドを含む検索インデックスを使用してデータをクエリし、ページネーションが必要な場合は、クエリ条件でデータを返すソート方法を指定する必要があります。そうしないと、クエリ条件を満たすデータの一部のみが読み取られた場合、Tablestore は nextToken を返しません。

  • ネストクエリは、他のタイプのクエリよりもパフォーマンスが低くなります。

ネストデータ型は、すべてのクエリ、ソート、および集計で使用できます。

参照

  • 検索インデックスを使用してデータをクエリする場合、次のクエリメソッドを使用できます。term クエリterms クエリmatch all クエリmatch クエリmatch phrase クエリprefix クエリrange クエリwildcard クエリfuzzy クエリブールクエリgeo クエリネストクエリKNN ベクトルクエリexists クエリ。ビジネス要件に基づいてクエリメソッドを選択し、複数のディメンションからデータをクエリできます。

    ソート機能とページング機能を使用して、クエリ条件を満たす行をソートまたはページネーションできます。詳細については、「ソートとページングを実行する」をご参照ください。

    collapse(distinct)機能を使用して、特定の列に基づいて結果セットを折りたたむことができます。これにより、指定されたタイプのデータはクエリ結果に 1 回だけ表示されます。詳細については、「Collapse(distinct)」をご参照ください。

  • データテーブルのデータを分析する場合は、検索操作の集計機能を使用するか、SQL ステートメントを実行できます。たとえば、最小値、最大値、合計、行の総数などを取得できます。詳細については、「集計」および「SQL クエリ」をご参照ください。

  • 行をソートする必要なく、クエリ条件を満たすすべての行を取得する場合は、ParallelScan 操作と ComputeSplits 操作を呼び出して並列スキャン機能を使用できます。詳細については、「並列スキャン」をご参照ください。