Todos os produtos
Search
Central de documentação

Tablestore:JSON

Última atualização: Jul 09, 2026

Os índices de busca aceitam o tipo de campo JSON. Mapeie uma coluna String de uma tabela de dados para um campo JSON em um índice de busca e execute buscas estruturadas e análises em dados semiestruturados. O tipo de campo JSON oferece dois modos de armazenamento: Object e Nested, adequados respectivamente para consultas a campos independentes e consultas correlacionadas de objetos aninhados.

Funcionamento

Ao mapear uma coluna String para um campo JSON em um índice de busca, o Tablestore analisa a estrutura JSON e indexa subcampos individuais para consulta. Dois modos de armazenamento estão disponíveis — Object e Nested — cada um otimizado para diferentes padrões de consulta.

  • Object: Achata estruturas aninhadas em campos de nível superior. Ideal para consultas simples a campos que exigem alto desempenho.

  • Nested: Preserva a independência e as associações de campos de cada objeto aninhado. Recomendado para consultas que exigem correspondência exata dentro de um único objeto aninhado.

Principais diferenças

Dimensão

Object

Nested

Processamento de dados

Achata dados aninhados em campos de nível superior

Armazena cada objeto aninhado como um documento independente

Método de consulta

Consultas padrão

Requer NestedQuery

Correlação de campos

Permite correspondência cruzada entre campos de diferentes objetos aninhados

Corresponde a campos apenas dentro do mesmo objeto aninhado

Desempenho

Menor consumo de recursos

Maior consumo de recursos; aceita consultas a campos correlacionados

Diretrizes de seleção

Escolha Nested quando as consultas precisarem preservar estritamente as correlações de campos dentro dos objetos aninhados. Opte por Object quando a prioridade for o alto desempenho de consulta e a correlação estrita de campos não for necessária.

Configurar e usar índices de campos JSON

Crie um índice de busca para campos JSON em três etapas: selecione um tipo JSON, configure o índice e execute consultas.

Independentemente da escolha entre Object ou Nested, defina explicitamente o tipo de cada subcampo. O índice ignora subcampos sem tipo definido, impedindo sua participação em consultas.

Etapa 1: Selecione o tipo JSON e o formato de dados

As seções a seguir comparam os tipos Object e Nested, mostram os formatos de dados compatíveis e demonstram como gravar dados JSON.

Seleção do tipo JSON

  • Object: Mais indicado para consultas a campos independentes. Oferece alto desempenho de consulta com baixo consumo de recursos.

  • Nested: Projetado para cenários de consulta que exigem correlação de campos. Garante resultados precisos dentro de cada objeto aninhado.

  • Híbrido: Combine os tipos Object e Nested no mesmo índice para atender a requisitos complexos.

Formato de dados

Campos JSON aceitam formatos de array e não-array. Escolha o formato com base na sua estrutura de dados:

// Array format
[{ "country": "China", "city": "Hangzhou" }, { "country": "USA", "city": "Seattle" }]

// Non-array format
{ "country": "China", "city": "Hangzhou" }

Gravar dados

private static void putRow(SyncClient client) {
    // Construct the primary key.
    PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
    primaryKeyBuilder.addPrimaryKeyColumn("id", PrimaryKeyValue.fromString("10001"));
    PrimaryKey primaryKey = primaryKeyBuilder.build();

    // Specify the table name.
    RowPutChange rowPutChange = new RowPutChange("<TABLE_NAME>", primaryKey);

    // Build the raw JSON data.
    List<Map<String, Object>> addresses = Arrays.asList(
    new HashMap<String, Object>() {{ put("country", "China"); put("city", "Hangzhou"); }},
    new HashMap<String, Object>() {{ put("country", "USA");   put("city", "Seattle"); }}
    );
    String jsonString = JSON.toJSONString(addresses); 

    rowPutChange.addColumn(new Column("address", ColumnValue.fromString(jsonString)));

    client.putRow(new PutRowRequest(rowPutChange));
}

Etapa 2: Configure a estrutura de campos e crie um índice

O exemplo a seguir configura um campo JSON de nível único com dois subcampos. Defina o tipo e as propriedades de cada subcampo para torná-los consultáveis.

List<FieldSchema> subFieldSchemas = new ArrayList<FieldSchema>();
subFieldSchemas.add(new FieldSchema("country", FieldType.KEYWORD)
    .setIndex(true).setEnableSortAndAgg(true));
subFieldSchemas.add(new FieldSchema("city", FieldType.KEYWORD)
    .setIndex(true).setEnableSortAndAgg(true));

FieldSchema jsonFieldSchema = new FieldSchema("address", FieldType.Json)
    .setJsonType(JsonType.OBJECT) // Set to JsonType.OBJECT or JsonType.NESTED
    .setSubFieldSchemas(subFieldSchemas);

Etapa 3: Consulte dados

  • Object: Achata dados aninhados. Acesse os campos concatenando os nomes dos campos pai e filho com um ponto (.). Como os campos são achatados, valores de diferentes objetos aninhados podem ter correspondência cruzada.

  • Nested: Preserva a independência de cada objeto aninhado. Envolva as condições de consulta em um NestedQuery para garantir que a correspondência de campos ocorra apenas dentro do mesmo objeto aninhado.

Formato indexado

Considere que o campo address contenha os seguintes dados: [{ "country": "China", "city": "Hangzhou" }, { "country": "USA", "city": "Seattle" }].

  • Formato indexado Object: {"address.country": ["China", "USA"], "address.city": ["Hangzhou","Seattle"]}

  • Formato indexado Nested: Documentos independentes { "country": "China", "city": "Hangzhou" } e { "country": "USA", "city": "Seattle" }

Com as condições address.country ="China" E address.city="Seattle", o tipo Object encontra correspondência (valores de campos entre objetos se combinam), mas o Nested não (nenhum objeto único possui ambos). Já com as condições address.country ="China" E address.city="Hangzhou", ambos os tipos encontram correspondência.

Exemplos de consulta

Exemplo de consulta do tipo JSON Nested

O exemplo a seguir consulta linhas em que o mesmo objeto aninhado do campo address satisfaz duas condições: address.country é "China" e address.city é "Seattle".

public static void nestedQuery(SyncClient client) {
    // Condition 1: The value of the country field in the address sub-row must be "China".
    TermQuery termQuery1 = new TermQuery();
    termQuery1.setFieldName("address.country");
    termQuery1.setTerm(ColumnValue.fromString("China"));

    // Condition 2: The value of the city field in the address sub-row must be "Seattle".
    TermQuery termQuery2 = new TermQuery();
    termQuery2.setFieldName("address.city");
    termQuery2.setTerm(ColumnValue.fromString("Seattle"));

    // Use the AND condition of BoolQuery to query for sub-rows that meet both conditions.
    List<Query> mustQueries = new ArrayList<>();
    mustQueries.add(termQuery1);
    mustQueries.add(termQuery2);
    BoolQuery boolQuery = new BoolQuery();
    boolQuery.setMustQueries(mustQueries);

    // Set BoolQuery within NestedQuery to require a sub-row to meet multiple query conditions at the same time.
    NestedQuery nestedQuery = new NestedQuery();    // Set the query type to NestedQuery.
    nestedQuery.setPath("address");   // Set the path of the nested type column, which is the parent path of the field to query.
    nestedQuery.setQuery(boolQuery);
    nestedQuery.setScoreMode(ScoreMode.None);

    SearchQuery searchQuery = new SearchQuery();
    searchQuery.setQuery(nestedQuery);

    SearchRequest searchRequest = new SearchRequest("<TABLE_NAME>", "<SEARCH_INDEX_NAME>", searchQuery);

    SearchResponse resp = client.search(searchRequest);
    System.out.println("Row: " + resp.getRows());
}

Exemplo de consulta do tipo JSON Object

O exemplo a seguir consulta linhas em que o campo address satisfaz duas condições em seus objetos aninhados: address.country é "China" e address.city é "Seattle".

public static void boolQuery(SyncClient client) {
    // Condition 1: The value of the country field in the address sub-row must be "China".
    TermQuery termQuery1 = new TermQuery();
    termQuery1.setFieldName("address.country");
    termQuery1.setTerm(ColumnValue.fromString("China"));

    // Condition 2: The value of the city field in the address sub-row must be "Seattle".
    TermQuery termQuery2 = new TermQuery();
    termQuery2.setFieldName("address.city");
    termQuery2.setTerm(ColumnValue.fromString("Seattle"));

    // Use the AND condition of BoolQuery to query for sub-rows that meet both conditions.
    List<Query> mustQueries = new ArrayList<>();
    mustQueries.add(termQuery1);
    mustQueries.add(termQuery2);
    BoolQuery boolQuery = new BoolQuery();
    boolQuery.setMustQueries(mustQueries);

    SearchQuery searchQuery = new SearchQuery();
    searchQuery.setQuery(boolQuery);

    SearchRequest searchRequest = new SearchRequest("<TABLE_NAME>", "<SEARCH_INDEX_NAME>", searchQuery);

    SearchResponse resp = client.search(searchRequest);
    System.out.println("Row: " + resp.getRows());
}

Exemplos de JSON

A configuração de esquema para campos JSON de nível único e multinível segue a mesma estrutura tanto para Object quanto para Nested. Apenas a definição de tipo difere.

JSON de nível único

O exemplo Java a seguir cria um campo JSON de nível único tags (selecione o tipo JSON conforme seus requisitos) com três subcampos:

  • tagName: Tipo Keyword. Usado para correspondência exata e agregação de nomes de tags.

  • score: Tipo Double. Usado para cálculos numéricos e ordenação de pesos de tags.

  • time: Tipo Date no formato epoch_millis. Usado para consultas de intervalo de tempo e análise de séries temporais.

Tanto formatos de array quanto de não-array são aceitos para gravação de dados:

// Array format
[{"tagName":"tag1", "score":0.8,"time": 1730690237000 }, {"tagName":"tag2", "score":0.2,"time": 1730691557000}]
// Non-array format
{"tagName":"tag1", "score":0.8,"time": 1730690237000 }

Configuração completa do esquema:

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 nestedFieldSchema = new FieldSchema("tags", FieldType.Json)
    .setJsonType(JsonType.OBJECT) // Replace with JsonType.NESTED as needed
    .setSubFieldSchemas(subFieldSchemas);

JSON multinível

O exemplo Java a seguir cria um campo JSON multinível user (selecione o tipo JSON conforme seus requisitos) com informações básicas do usuário e dados de endereço aninhados. Campos JSON multiníveis aceitam uma mistura de tipos Nested e Object.

  • Campos básicos: name (Keyword, para consultas exatas de nome), age (Long, para filtragem por faixa etária), birth (Date, formato yyyy-MM-dd HH:mm:ss.SSS, para consultas de aniversário), phone (Keyword, para correspondência de contato).

  • Campo aninhado: address (selecione o tipo JSON conforme seus requisitos), contendo province, city e street (todos do tipo Keyword) para consultas hierárquicas de localização.

Dados de usuário de exemplo:

{
  "name": "John",
  "age": 20,
  "birth": "2014-10-10 12:00:00.000",
  "phone": "1390000****",
  "address": {
    "province": "Zhejiang",
    "city": "Hangzhou",
    "street": "1201, Sunshine Community, Yangguang Avenue"
  }
}

Configuração completa do esquema para JSON multinível:

// Sub-field schema for address (path: 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));

// Sub-field schema for user (path: 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.JSON)
    .setJsonType(JsonType.NESTED) // Replace with JsonType.OBJECT as needed
    .setSubFieldSchemas(addressSubFiledSchemas));

// Create the parent field: user
List<FieldSchema> fieldSchemas = new ArrayList<>();
fieldSchemas.add(new FieldSchema("user",FieldType.JSON)
    .setJsonType(JsonType.OBJECT) // Replace with JsonType.NESTED as needed
    .setSubFieldSchemas(subFieldSchemas));

Limitações

  • Campos vetoriais: Não use campos vetoriais como subcampos de um campo JSON. Configure índices de campos vetoriais independentemente.

  • Tipo Nested: Campos JSON Nested não aceitam pré-ordenação de índice. Use NestedQuery para consultar campos aninhados.

  • Subcampos de array: Para subcampos não-JSON com dados em formato de array, defina a propriedade IsArray como true. Grave dados no formato de array padrão "[a, b, c]". Caso contrário, o índice não consegue sincronizar ou consultar o subcampo.

Referências

Atualmente, o tipo de campo JSON é compatível com o Tablestore SDK for Java, o Tablestore SDK for Go e o Tablestore SDK for Python.