Como estruturar dados com uma consistência forte

O Datastore fornece alta disponibilidade, escalonabilidade e durabilidade ao distribuir dados em muitas máquinas e usar replicação síncrona sem mestre em uma ampla área geográfica. A desvantagem deste modelo é que a capacidade de gravação de um grupo de entidades único é limitada a aproximadamente um commit por segundo. Há também limitações em consultas ou transações que abrangem vários grupos de entidades. Esta página descreve essas limitações com mais detalhes e discute as práticas recomendadas para estruturar os dados de modo a oferecer suporte a uma consistência forte e satisfazer os requisitos de capacidade de gravação do aplicativo.

Níveis de consistência

As consultas do Datastore podem gerar resultados em dois níveis de consistência:

  • Consultas com consistência forte garantem os resultados mais atualizados, mas podem ser mais demoradas ou incompatíveis em determinados casos.
  • Consultas com consistência eventual costumam ser mais rápidas, mas podem retornar resultados desatualizados.

Em uma consulta com consistência eventual, os índices usados para coletar os resultados também são acessados com esse tipo de consistência. Consequentemente, essas consultas podem, algumas vezes, retornar entidades que não correspondem mais aos critérios de consulta, além de omitir algumas que correspondem. As consultas com consistência forte são consistentes de forma transacional, o que significa que os resultados são baseados em um instantâneo único e consistente dos dados.

Garantias de consistência

As consultas retornam resultados com diferentes níveis de garantia de consistência, dependendo da natureza da consulta:

  • Consultas de ancestrais, executadas em um grupo de entidades, têm consistência forte por padrão. No entanto, para que tenham consistência eventual, configure a política de leitura do Datastore abordada abaixo.
  • As consultas globais, que não são executadas em um grupo de entidades, sempre têm consistência eventual.

Em muitos aplicativos, é aceitável usar a consistência eventual para ter uma visualização ampla dos dados não relacionados e depois usar a consistência forte ao visualizar ou editar um único conjunto de dados altamente relacionados. Por exemplo, uma consulta global abrangendo vários grupos de entidades, que algumas vezes pode retornar dados ligeiramente desatualizados, seguida de uma consulta de ancestral ou uma pesquisa de uma única entidade. Em tais aplicativos, é recomendado colocar os dados altamente relacionados em grupos de entidades. Um número maior desses grupos aumenta a capacidade, enquanto um número menor aumenta o volume de entidades que podem ser lidas em uma única consulta de ancestral. O aplicativo precisa levar isso em conta para determinar o equilíbrio certo entre capacidade e consistência.

Política de leitura do Datastore

Para aumentar o desempenho, você pode definir a política de leitura de uma consulta para que os resultados tenham consistência eventual. A API Datastore também permite definir explicitamente uma política de consistência forte, mas essa configuração não tem efeito prático, já que as consultas globais sempre têm consistência eventual, independentemente da política.

Você pode ativar leituras com consistência eventual nas opções de leitura do objeto de consulta:

C#

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API C# do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

Query query = new Query("Task")
{
    Filter = Filter.HasAncestor(_db.CreateKeyFactory("TaskList")
        .CreateKey(keyName))
};
var results = _db.RunQuery(query,
    ReadOptions.Types.ReadConsistency.Eventual);

Go

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Go do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

ancestor := datastore.NameKey("TaskList", "default", nil)
query := datastore.NewQuery("Task").Ancestor(ancestor).EventualConsistency()

Java

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Java do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

Query<Entity> query =
    Query.newEntityQueryBuilder()
        .setKind("Task")
        .setFilter(
            PropertyFilter.hasAncestor(
                datastore.newKeyFactory().setKind("TaskList").newKey("default")))
        .build();
datastore.run(query, ReadOption.eventualConsistency());

Node.js

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Node.js do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

const ancestorKey = datastore.key(['TaskList', 'default']);
const query = datastore.createQuery('Task').hasAncestor(ancestorKey);

query.run({consistency: 'eventual'});

PHP

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API PHP do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

$query = $datastore->query()
    ->kind('Task')
    ->hasAncestor($datastore->key('TaskList', 'default'));
$result = $datastore->runQuery($query, ['readConsistency' => 'EVENTUAL']);

Python

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Python do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

from google.cloud import datastore

# For help authenticating your client, visit
# https://cloud.google.com/docs/authentication/getting-started
client = datastore.Client()

query = client.query(kind="Task")
query.fetch(eventual=True)

Ruby

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Ruby do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

# task_list_name = "default"
ancestor_key = datastore.key "TaskList", task_list_name

query = datastore.query("Task")
                 .ancestor(ancestor_key)

tasks = datastore.run query, consistency: :eventual

Considerações sobre transações e consistência

As confirmações do Datastore são transacionais quando ocorrem no contexto de uma transação e o conjunto de mutações dessa transação é totalmente aplicado ou totalmente não aplicado. Elas são não transacionais quando não há possibilidade de aplicar o conjunto de mutações dessa forma.

Uma única transação pode incluir qualquer número de mudanças de criação, atualização ou exclusão. Para manter a consistência dos dados, a transação assegura que todas as mudanças que ela contém sejam aplicadas ao Datastore como uma unidade ou, se alguma das mudanças apresentar falhas, que nenhuma delas seja aplicada. Além disso, todas as leituras com consistência forte (consultas de ancestral ou operações lookup) realizadas na mesma transação dependem de um snapshot único e consistente dos dados. As consultas com consistência forte precisam especificar um filtro de ancestral. As consultas que participam de uma transação sempre têm consistência forte. As transações podem envolver no máximo 25 grupos de entidades. As leituras com consistência eventual não têm essas limitações e são adequadas em muitos casos. O uso de leituras com consistência eventual pode permitir que você distribua os dados entre um número maior de grupos de entidades, permitindo que você obtenha maior capacidade de gravação executando commits paralelamente nos diferentes grupos de entidades. No entanto, você precisa compreender as características das leituras com consistência eventual para determinar se elas são adequadas para o seu aplicativo:

  • Os resultados dessas leituras podem não refletir as transações mais recentes. Isso pode ocorrer porque essas leituras não garantem que a réplica na qual elas estão sendo executadas está atualizada. Em vez disso, elas usam os dados disponíveis na réplica no momento da execução da consulta.
  • Uma transação com commit que abrange vários grupos de entidades pode parecer ter sido aplicada a algumas entidades, e não a outras. Observe, no entanto, que uma transação nunca parecerá ter sido parcialmente aplicada em uma única entidade.
  • Os resultados da consulta podem incluir entidades que não deveriam ter sido incluídas de acordo com os critérios de filtro e podem excluir entidades que deveriam ter sido incluídas. Isso pode ocorrer porque a versão do instantâneo usada para ler índices pode diferir da versão do instantâneo usada para ler a entidade.

Como estruturar os dados para consistência

Para compreender como estruturar os dados para uma consistência forte, compare duas abordagens diferentes para um simples aplicativo de lista de tarefas. A primeira abordagem cria cada entidade no seu próprio grupo de entidades novo (isto é, cada entidade é uma entidade raiz):

C#

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API C# do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

Entity task = new Entity()
{
    Key = _db.CreateKeyFactory("Task").CreateKey("sampleTask"),
    ["category"] = "Personal",
    ["done"] = false,
    ["priority"] = 4,
    ["description"] = "Learn Cloud Datastore"
};

Go

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Go do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

type Task struct {
	Category        string
	Done            bool
	Priority        float64
	Description     string `datastore:",noindex"`
	PercentComplete float64
	Created         time.Time
}
task := &Task{
	Category:        "Personal",
	Done:            false,
	Priority:        4,
	Description:     "Learn Cloud Datastore",
	PercentComplete: 10.0,
	Created:         time.Now(),
}

Java

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Java do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

Key taskKey = datastore.newKeyFactory().setKind("Task").newKey("sampleTask");
Entity task =
    Entity.newBuilder(taskKey)
        .set("category", "Personal")
        .set("done", false)
        .set("priority", 4)
        .set("description", "Learn Cloud Datastore")
        .build();

Node.js

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Node.js do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

const task = {
  category: 'Personal',
  done: false,
  priority: 4,
  description: 'Learn Cloud Datastore',
};

PHP

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API PHP do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

$task = $datastore->entity('Task', [
    'category' => 'Personal',
    'done' => false,
    'priority' => 4,
    'description' => 'Learn Cloud Datastore'
]);

Python

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Python do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

from google.cloud import datastore

# For help authenticating your client, visit
# https://cloud.google.com/docs/authentication/getting-started
client = datastore.Client()

task = datastore.Entity(client.key("Task"))
task.update(
    {
        "category": "Personal",
        "done": False,
        "priority": 4,
        "description": "Learn Cloud Datastore",
    }
)

Ruby

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Ruby do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

task = datastore.entity "Task" do |t|
  t["category"] = "Personal"
  t["done"] = false
  t["priority"] = 4
  t["description"] = "Learn Cloud Datastore"
end

Essa abordagem consulta no tipo de entidade Task para as tarefas que ainda não foram realizadas com prioridades maiores ou iguais a 4, classificadas em ordem decrescente por prioridade:

C#

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API C# do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

Query query = new Query("Task")
{
    Filter = Filter.And(Filter.Equal("done", false),
        Filter.GreaterThanOrEqual("priority", 4)),
    Order = { { "priority", PropertyOrder.Types.Direction.Descending } }
};

Go

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Go do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

query := datastore.NewQuery("Task").
	FilterField("Done", "=", false).
	FilterField("Priority", ">=", 4).
	Order("-Priority")

Java

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Java do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

Query<Entity> query =
    Query.newEntityQueryBuilder()
        .setKind("Task")
        .setFilter(
            CompositeFilter.and(
                PropertyFilter.eq("done", false), PropertyFilter.ge("priority", 4)))
        .setOrderBy(OrderBy.desc("priority"))
        .build();

Node.js

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Node.js do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

const query = datastore
  .createQuery('Task')
  .filter(
    and([
      new PropertyFilter('done', '=', false),
      new PropertyFilter('priority', '>=', 4),
    ])
  )
  .order('priority', {
    descending: true,
  });

PHP

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API PHP do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

$query = $datastore->query()
    ->kind('Task')
    ->filter('done', '=', false)
    ->filter('priority', '>=', 4)
    ->order('priority', Query::ORDER_DESCENDING);

Python

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Python do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

from google.cloud import datastore

# For help authenticating your client, visit
# https://cloud.google.com/docs/authentication/getting-started
client = datastore.Client()

query = client.query(kind="Task")
query.add_filter(filter=datastore.query.PropertyFilter("done", "=", False))
query.add_filter(filter=datastore.query.PropertyFilter("priority", ">=", 4))
query.order = ["-priority"]

Ruby

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Ruby do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

query = datastore.query("Task")
                 .where("done", "=", false)
                 .where("priority", ">=", 4)
                 .order("priority", :desc)

No entanto, como estamos usando uma consulta de consistência eventual em vez de uma consulta de ancestral, os resultados talvez não contenham a nova entidade. Contudo, quase todas as gravações estarão disponíveis para consultas com consistência eventual logo após o commit. Para muitos aplicativos, uma solução que fornece os resultados de uma consulta com consistência eventual no contexto das próprias alterações do usuário atual normalmente será suficiente para tornar essas latências completamente aceitáveis.

Para alcançar uma consistência forte, a melhor abordagem seria criar as entidades com um caminho de ancestral. Esse caminho identifica a entidade raiz comum na qual as entidades criadas são agrupadas. Este exemplo usa um caminho ancestral do tipo TaskList chamado default:

C#

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API C# do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

Key taskListKey = _db.CreateKeyFactory("TaskList").CreateKey(TestUtil.RandomName());
Key taskKey = new KeyFactory(taskListKey, "Task").CreateKey("sampleTask");
Entity task = new Entity()
{
    Key = taskKey,
    ["category"] = "Personal",
    ["done"] = false,
    ["priority"] = 4,
    ["description"] = "Learn Cloud Datastore"
};

Go

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Go do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

parentKey := datastore.NameKey("TaskList", "default", nil)
key := datastore.IncompleteKey("Task", parentKey)

task := Task{
	Category:    "Personal",
	Done:        false,
	Priority:    4,
	Description: "Learn Cloud Datastore",
}

// A complete key is assigned to the entity when it is Put.
var err error
key, err = client.Put(ctx, key, &task)

Java

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Java do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

Key taskKey =
    datastore
        .newKeyFactory()
        .addAncestors(PathElement.of("TaskList", "default"))
        .setKind("Task")
        .newKey("sampleTask");
Entity task =
    Entity.newBuilder(taskKey)
        .set("category", "Personal")
        .set("done", false)
        .set("priority", 4)
        .set("description", "Learn Cloud Datastore")
        .build();

Node.js

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Node.js do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

const taskKey = datastore.key([
  'TaskList',
  'default',
  'Task',
  'sampleTask',
]);

const task = {
  key: taskKey,
  data: {
    category: 'Personal',
    done: false,
    priority: 4,
    description: 'Learn Cloud Datastore',
  },
};

PHP

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API PHP do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

$parentKey = $datastore->key('TaskList', 'default');
$key = $datastore->key('Task')->ancestorKey($parentKey);
$task = $datastore->entity(
    $key,
    [
        'Category' => 'Personal',
        'Done' => false,
        'Priority' => 4,
        'Description' => 'Learn Cloud Datastore'
    ]
);

Python

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Python do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

from google.cloud import datastore

# For help authenticating your client, visit
# https://cloud.google.com/docs/authentication/getting-started
client = datastore.Client()

key_with_parent = client.key("TaskList", "default", "Task", "sampleTask")

task = datastore.Entity(key=key_with_parent)

task.update(
    {
        "category": "Personal",
        "done": False,
        "priority": 4,
        "description": "Learn Cloud Datastore",
    }
)

Ruby

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Ruby do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

# task_list_name = "default"
# task_name = "sampleTask"
task_key = datastore.key [["TaskList", task_list_name], ["Task", task_name]]

task = datastore.entity task_key do |t|
  t["category"] = "Personal"
  t["done"] = false
  t["priority"] = 4
  t["description"] = "Learn Cloud Datastore"
end

Você conseguirá executar uma consulta de ancestral de consistência forte dentro do grupo de entidades identificado pela entidade raiz comum:

C#

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API C# do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

Query query = new Query("Task")
{
    Filter = Filter.HasAncestor(_db.CreateKeyFactory("TaskList")
        .CreateKey(keyName))
};

Go

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Go do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

ancestor := datastore.NameKey("TaskList", "default", nil)
query := datastore.NewQuery("Task").Ancestor(ancestor)

Java

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Java do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

Query<Entity> query =
    Query.newEntityQueryBuilder()
        .setKind("Task")
        .setFilter(
            PropertyFilter.hasAncestor(
                datastore.newKeyFactory().setKind("TaskList").newKey("default")))
        .build();

Node.js

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Node.js do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

const ancestorKey = datastore.key(['TaskList', 'default']);

const query = datastore.createQuery('Task').hasAncestor(ancestorKey);

PHP

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API PHP do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

$ancestorKey = $datastore->key('TaskList', 'default');
$query = $datastore->query()
    ->kind('Task')
    ->hasAncestor($ancestorKey);

Python

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Python do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

from google.cloud import datastore

# For help authenticating your client, visit
# https://cloud.google.com/docs/authentication/getting-started
client = datastore.Client()

# Query filters are omitted in this example as any ancestor queries with a
# non-key filter require a composite index.
ancestor = client.key("TaskList", "default")
query = client.query(kind="Task", ancestor=ancestor)

Ruby

Para saber como instalar e usar a biblioteca de cliente do Cloud Datastore, consulte Bibliotecas de cliente do Cloud Datastore. Para mais informações, consulte a documentação de referência da API Ruby do Cloud Datastore.

Para autenticar no Cloud Datastore, configure o Application Default Credentials. Para mais informações, consulte Configurar a autenticação para um ambiente de desenvolvimento local.

# task_list_name = "default"
ancestor_key = datastore.key "TaskList", task_list_name

query = datastore.query("Task")
                 .ancestor(ancestor_key)

Essa abordagem alcança consistência forte ao gravar em um único grupo de entidades por lista de tarefas. No entanto ela limita as alterações na lista de tarefas a até 1 gravação por segundo, que é o limite permitido para grupos de entidades. É provável que o aplicativo encontre um uso mais intensivo de gravação. Nesse caso, analise o uso de outros meios. Por exemplo, se o aplicativo for um livro de visitas que permite que os usuários postem mensagens em um quadro de mensagens público, você poderá colocar as postagens recentes no memcache com uma expiração e exibir uma combinação de postagens recentes do memcache e do Datastore ou poderá armazená-las em cache em um cookie, colocar algum estado no URL ou outra opção. O objetivo é encontrar uma solução de armazenamento em cache que forneça os dados para o usuário atual durante o período de tempo em que o usuário está postando no aplicativo. Lembre-se de que você sempre verá os dados gravados mais recentemente ao realizar uma operação lookup, uma consulta de ancestral (supondo que a política de leitura não está definida para a consistência eventual) ou qualquer operação em uma transação.

Para ver mais exemplos de como usar transações, acesse este link.

Limitações de grupos de entidades em transações

A organização dos dados em grupos de entidades pode limitar quais transações podem ser realizadas:

  • Todos os dados acessados por uma transação devem estar contidos em, no máximo, 25 grupos de entidades.
  • Se você quiser usar consultas em uma transação, os dados precisam estar organizados em grupos de entidades para que você possa especificar filtros de ancestral que corresponderão aos dados corretos.
  • Há um limite de capacidade de gravação de aproximadamente uma transação por segundo para um único grupo de entidades. Essa limitação existe porque, para fornecer alta confiabilidade e tolerância a falhas, o Datastore executa a replicação síncrona sem mestre de cada grupo de entidades em uma ampla área geográfica.

Para mais informações sobre como as entidades e os índices são atualizados, leia o artigo Isolamento da transação.