Index

Chaque requête Firestore en mode Datastore calcule ses résultats au moyen d'un ou de plusieurs index, qui contiennent des clés d'entité dans une séquence spécifiée par leurs propriétés et, éventuellement, par les ancêtres de l'entité. Les index sont mis à jour pour refléter les modifications apportées par l'application à ses entités, afin que les résultats corrects de toutes les requêtes soient disponibles sans qu'aucun calcul supplémentaire ne soit nécessaire.

Il existe deux types d'index :

Index intégrés
Par défaut, une base de données en mode Datastore prédéfinit automatiquement un index pour chaque propriété de chaque genre d'entité. Ces index de propriété uniques sont adaptés à des types de requêtes simples.
Index composites
Les index composites indexent plusieurs valeurs de propriété par entité indexée. Ils acceptent les requêtes complexes et sont définis dans un fichier de configuration d'index (index.yaml).

Les types d'index sont abordés plus en détail dans différentes sections de cette page.

Définition et structure des index

Un index est défini sur une liste de propriétés d'un genre d'entité donné, avec un ordre correspondant (croissant ou décroissant) pour chaque propriété. Pour une utilisation avec des requêtes ascendantes, l'index peut également inclure les ancêtres d'une entité.

Une table d'index contient une colonne pour chaque propriété nommée dans la définition de l'index. Chaque ligne de la table représente une entité qui constitue un résultat potentiel pour les requêtes basées sur l'index. Une entité n'est incluse dans l'index que si un ensemble de valeurs indexées est défini pour chaque propriété utilisée dans l'index. Si la définition de l'index fait référence à une propriété pour laquelle l'entité n'a pas de valeur, cette entité n'apparaîtra pas dans l'index et ne sera donc jamais renvoyée comme résultat pour toute requête basée sur l'index.

Les lignes d'une table d'index sont d'abord triées par ancêtre, puis par valeur de propriété, dans l'ordre spécifié dans la définition d'index. L'index parfait pour une requête, permettant de l'exécuter de manière plus efficace, est défini dans les propriétés ci-dessous. Dans l'ordre :

  1. Propriétés utilisées dans les filtres d'égalité.
  2. Propriété utilisée dans un filtre d'inégalité (il ne peut pas y en avoir plus d'un).
  3. Propriétés utilisées dans les ordres de tri
  4. Propriétés utilisées dans les projections (qui ne sont pas déjà incluses dans les ordres de tri)

Cela garantit que tous les résultats pour chaque exécution possible de la requête apparaissent dans des lignes consécutives de la table. Les bases de données en mode Datastore exécutent une requête avec un index parfait en procédant comme suit :

  1. Il identifie l'index correspondant au genre de la requête, aux propriétés du filtre, aux opérateurs de filtre et aux ordres de tri.
  2. Il effectue une analyse en partant du début de l'index jusqu'à la première entité répondant à toutes les conditions de filtre de la requête
  3. Il continue l'analyse de l'index, en renvoyant tour à tour chaque entité, jusqu'à :
    • rencontre une entité ne répondant pas aux conditions de filtre ;
    • atteigne la fin de l'index ;
    • ait collecté le nombre maximal de résultats demandés par la requête.

Par exemple, examinez la requête suivante :

SELECT * FROM Task
WHERE category = 'Personal'
  AND priority < 3
ORDER BY priority DESC

L'index parfait pour cette requête est une table de clés pour les entités de genre Task, avec des colonnes pour les valeurs des propriétés category et priority. L'index est d'abord trié par ordre croissant de category, puis par ordre décroissant de priority.

indexes:
- kind: Task
  properties:
  - name: category
    direction: asc
  - name: priority
    direction: desc

Deux requêtes ayant la même forme, mais avec des valeurs de filtrage différentes utilisant le même index. Par exemple, la requête suivante utilise le même index que ci-dessus :

SELECT * FROM Task
WHERE category = 'Work'
  AND priority < 5
ORDER BY priority DESC

Pour cet index,

indexes:
- kind: Task
  properties:
  - name: category
    direction: asc
  - name: priority
    direction: asc
  - name: created
    direction: asc

les deux requêtes suivantes utilisent également le même index, bien que leurs formes soient différentes :

SELECT * FROM Task
WHERE category = 'Personal'
  AND priority = 5
ORDER BY created ASC

et

SELECT * FROM Task
WHERE category = 'Work'
ORDER BY priority ASC, created ASC

L'index créé ci-dessus permet de satisfaire ces deux requêtes.

Configuration des index

Firestore en mode Datastore fournit des index intégrés ou automatiques pour les requêtes qui se présentent sous les formes suivantes :

  • Les requêtes sans genre n'utilisant que des filtres d'ancêtre et de clé
  • Les requêtes n'utilisant que des filtres d'ancêtre et d'égalité
  • Les requêtes n'utilisant que des filtres d'inégalité (limités à une seule propriété)
  • Les requêtes n'utilisant que des filtres d'ancêtre, des filtres d'égalité sur les propriétés et des filtres d'inégalité sur les clés
  • Les requêtes n'utilisant pas de filtre et un seul ordre de tri sur une propriété, croissant ou décroissant

Par exemple, les bases de données en mode Datastore prédéfinissent automatiquement par défaut deux index de propriété uniques pour chaque propriété de chaque genre d'entité, l'un dans l'ordre croissant et l'autre dans l'ordre décroissant. Si vous ne souhaitez pas que votre base de données gère un index pour une propriété, excluez la propriété de vos index. Notez que le fait d'exclure une propriété la supprime de tous les index composites.

Les index intégrés suffisent à exécuter de nombreuses requêtes simples, telles que les requêtes à égalité stricte et les requêtes à inégalité simples.

Les index intégrés n'apparaissent pas sur la page Index de la console Google Cloud.

Pour les requêtes plus complexes, une application doit définir des index composites ou manuels. Les index composites sont requis pour les requêtes qui se présentent sous les formes suivantes :

  • Les requêtes avec filtres d'ancêtre et d'inégalité
  • Les requêtes avec un ou plusieurs filtres d'inégalité sur une propriété et un ou plusieurs filtres d'égalité sur d'autres propriétés
  • Les requêtes avec un ordre de tri décroissant sur les clés
  • Les requêtes avec plusieurs ordres de tri
  • Les requêtes avec un ou plusieurs filtres et un ou plusieurs ordres de tri

Les index composites sont définis dans le fichier de configuration d'index de l'application (index.yaml). (Les index intégrés ne figurent pas dans le fichier de configuration d'index.)

Les index composites incluent plusieurs propriétés et exigent que chaque propriété ne soit pas exclue de vos index.

Les index composites sont visibles sur la page Index de la console Google Cloud. Vous ne pouvez pas utiliser la console Google Cloud pour créer ou mettre à jour des index composites.

Si l'application essaie d'exécuter une requête ne pouvant pas être exécutée avec les index disponibles (intégrés ou spécifiés dans le fichier de configuration d'index), la requête échouera.

L'API en mode Datastore suggère automatiquement des index appropriés pour la plupart des applications. La manière dont votre application utilise votre base de données en mode Datastore, ainsi que la taille et la forme de vos données, peuvent justifier un ajustement manuel de vos index. Par exemple, l'écriture d'entités avec plusieurs valeurs de propriété peut entraîner un index exponentiel avec des coûts de stockage élevés et une latence d'écriture accrue.

L'émulateur Datastore peut contribuer à faciliter la gestion du fichier de configuration d'index. Au lieu de faire échouer l'exécution d'une requête nécessitant un index lorsqu'il n'y en a pas, l'émulateur Datastore peut générer une configuration d'index permettant à la requête de réussir. Si vous réalisez en local des tests couvrant toutes les requêtes que votre application est susceptible d'effectuer, en utilisant chaque combinaison de filtre et d'ordre de tri, les entrées générées constituent un ensemble complet d'index. Si vos tests n'exécutent pas tous les formulaires de requête possibles, vous pouvez consulter et ajuster le fichier de configuration d'index avant de mettre à jour les index.

Pour en savoir plus sur le fichier index.yaml, consultez la page Configuration de l'index.

Déployer ou supprimer un index

Lorsque vous avez terminé de modifier le fichier de configuration d'index, exécutez la commande gcloud datastore indexes create pour placer les index dans le service. Consultez la section Mettre à jour des index pour en savoir plus.

Si vous avez déjà déployé des index dont vous n'avez plus besoin, vous pouvez supprimer les index non utilisés.

Coûts de stockage et latence d'écriture

Les index contribuent à vos coûts de stockage. La taille des entrées d'index décrit la façon dont les index intégrés et composites contribuent à la taille de stockage de votre base de données. Vous pouvez utiliser les statistiques de Firestore en mode Datastore pour afficher plus d'informations sur les entrées d'index et la taille de stockage des index.

Les index contribuent également à la latence d'écriture. Lors de la mise à jour d'une valeur de propriété, la base de données met également à jour chaque index associé. Plus les index à mettre à jour par la base de données sont nombreux, plus l'opération prend du temps.

Vous pouvez réduire vos coûts de stockage et améliorer les performances en écriture en supprimant les index inutilisés et en excluant les propriétés de l'indexation. Cela évite également l'échec des opérations en raison de limites d'index.

Index et propriétés

Vous trouverez ci-dessous quelques considérations spécifiques à prendre en compte au sujet des index et de leur relation avec les propriétés des entités.

Propriétés avec des valeurs de différents types

Lorsque deux entités possèdent des propriétés du même nom mais des valeurs de types différents, un index de la propriété les trie d'abord par type de valeur, puis dans un ordre secondaire approprié à chaque type. Par exemple, si deux entités possèdent chacune une propriété nommée age, l'une avec une valeur entière et l'autre avec une valeur de chaîne, l'entité avec la valeur entière précède toujours celle avec la valeur de chaîne lorsqu'elle est triée selon la propriété age, indépendamment des valeurs de propriété.

Cela vaut particulièrement pour les entiers et les nombres à virgule flottante, qui sont considérés comme des types distincts par le mode Datastore. Comme les entiers sont triés avant les nombres à virgule flottante, cela signifie qu'une propriété avec la valeur entière 38 précède une propriété avec la valeur à virgule flottante 37.5.

Propriétés exclues

Si vous savez que vous ne devrez jamais filtrer ou trier une propriété spécifique, vous pouvez indiquer à votre base de données en mode Datastore de ne pas conserver les entrées d'index de cette propriété en l'excluant des index. Cette opération permet de réduire le coût d'exécution de votre application en réduisant la taille de stockage nécessaire aux entrées d'index. Cela peut également améliorer la latence d'écriture. Une entité avec une propriété exclue se comporte comme si la propriété n'était pas définie : les requêtes avec un filtre ou un ordre de tri sur la propriété exclue ne correspondront jamais à cette entité.

La propriété description dans l'exemple suivant est exclue des index :

C#

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore C#.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

Entity task = new Entity()
{
    Key = _db.CreateKeyFactory("Task").CreateKey("sampleTask"),
    ["category"] = "Personal",
    ["created"] = new DateTime(1999, 01, 01, 0, 0, 0, DateTimeKind.Utc),
    ["done"] = false,
    ["priority"] = 4,
    ["percent_complete"] = 10.0,
    ["description"] = new Value()
    {
        StringValue = "Learn Cloud Datastore",
        ExcludeFromIndexes = true
    },
};

Go

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore Go.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

type Task struct {
	Category        string
	Done            bool
	Priority        int
	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

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore Java.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

Entity task =
    Entity.newBuilder(taskKey)
        .set("category", "Personal")
        .set("created", Timestamp.now())
        .set("done", false)
        .set("priority", 4)
        .set("percent_complete", 10.0)
        .set(
            "description",
            StringValue.newBuilder("Learn Cloud Datastore").setExcludeFromIndexes(true).build())
        .build();

Node.js

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore Node.js.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

const task = [
  {
    name: 'category',
    value: 'Personal',
  },
  {
    name: 'created',
    value: new Date(),
  },
  {
    name: 'done',
    value: false,
  },
  {
    name: 'priority',
    value: 4,
  },
  {
    name: 'percent_complete',
    value: 10.0,
  },
  {
    name: 'description',
    value: 'Learn Cloud Datastore',
    excludeFromIndexes: true,
  },
];

PHP

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore PHP.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

$task = $datastore->entity(
    $key,
    [
        'category' => 'Personal',
        'created' => new DateTime(),
        'done' => false,
        'priority' => 4,
        'percent_complete' => 10.0,
        'description' => 'Learn Cloud Datastore'
    ],
    ['excludeFromIndexes' => ['description']]
);

Python

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore Python.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

from google.cloud import datastore

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

key = client.key("Task")
task = datastore.Entity(key, exclude_from_indexes=("description",))
task.update(
    {
        "category": "Personal",
        "description": "Learn Cloud Datastore",
        "created": datetime.datetime.now(tz=datetime.timezone.utc),
        "done": False,
        "priority": 4,
        "percent_complete": 10.5,
    }
)
client.put(task)

Ruby

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore Ruby.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

task = datastore.entity "Task" do |t|
  t["category"] = "Personal"
  t["created"] = Time.now
  t["done"] = false
  t["priority"] = 4
  t["percent_complete"] = 10.0
  t["description"] = "Learn Cloud Datastore"
  t.exclude_from_indexes! "description", true
end

GQL

Non applicable

La requête dans l'exemple suivant ne renverra aucun résultat si la propriété description a été exclue :

C#

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore C#.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

Query query = new Query("Task")
{
    Filter = Filter.Equal("description", "Learn Cloud Datastore")
};

Go

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore Go.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

query := datastore.NewQuery("Tasks").
	FilterField("Description", "=", "A task description")

Java

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore Java.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

Query<Entity> query =
    Query.newEntityQueryBuilder()
        .setKind("Task")
        .setFilter(PropertyFilter.eq("description", "A task description"))
        .build();

Node.js

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore Node.js.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

const query = datastore
  .createQuery('Task')
  .filter(new PropertyFilter('description', '=', 'A task description.'));

PHP

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore PHP.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

$query = $datastore->query()
    ->kind('Task')
    ->filter('description', '=', 'A task description.');

Python

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore Python.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement 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=PropertyFilter("description", "=", "Learn Cloud Datastore"))

Ruby

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore Ruby.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

query = datastore.query("Task")
                 .where("description", "=", "A task description.")

GQL


# Will not return any results!
SELECT * FROM Task WHERE description = 'A task description.'

Vous pouvez modifier la propriété plus tard pour qu'elle redevienne indexée.

Toutefois, veuillez prendre en compte que le fait d'indexer une propriété exclue n'a aucune incidence sur les entités qui ont été éventuellement créées avant la modification. Les requêtes de filtre sur la propriété ne renverront pas de telles entités existantes, car elles n'ont pas été écrites dans l'index de la requête lors de leur création. Pour rendre les entités accessibles par les futures requêtes, vous devez les réécrire dans votre base de données afin de les inclure dans les index appropriés. En d'autres termes, vous devez effectuer les opérations suivantes pour chacune de ces entités existantes :

  1. Rechercher (get) l'entité.
  2. Écrire (put) de nouveau l'entité dans votre base de données.

De même, le fait d'exclure une propriété indexée n'a une incidence que sur les entités écrites ultérieurement dans votre base de données. Les entrées d'index pour n'importe quelle entité existante avec cette propriété continueront d'exister jusqu'à ce que les entités soient mises à jour ou supprimées. Pour éviter des résultats indésirables, vous devez purger votre code de toutes les requêtes de filtre ou de tri en fonction de la propriété (désormais exclue).

Limites relatives aux index

Firestore en mode Datastore impose des limites concernant le nombre et la taille globale des entrées d'index pouvant être associées à une seule entité. Ces limites sont élevées et la plupart des applications ne sont pas affectées. Toutefois, il existe des circonstances dans lesquelles vous pourriez y être confronté.

Comme décrit ci-dessus, une base de données en mode Datastore crée une entrée dans un index prédéfini pour chaque propriété de chaque entité, à l'exception de celles que vous avez explicitement déclarées comme exclues de vos index. La propriété peut également être incluse dans des index personnalisés supplémentaires, déclarés dans le fichier de configuration d'index (index.yaml). Si une entité ne possède pas de propriétés de liste, elle affichera au maximum une entrée dans chacun de ces index personnalisés (pour les index non-ancêtres) ou une entrée pour chacun des ancêtres de l'entité (pour les index ancêtres). Chacune de ces entrées d'index doit être mise à jour chaque fois que la valeur de la propriété change.

Pour une propriété avec une valeur unique pour chaque entité, chaque valeur possible doit être stockée une seule fois par entité dans l'index prédéfini de la propriété. Même dans ce cas, il est possible pour une entité avec un grand nombre de propriétés à une seule valeur d'atteindre la limite d'entrée ou de taille maximale de l'index. De même, une entité pouvant avoir plusieurs valeurs pour la même propriété nécessite une entrée d'index distincte pour chaque valeur. Là encore, si le nombre de valeurs possibles est important, une entité de ce type peut dépasser la limite d'entrée.

La situation s'aggrave dans le cas d'entités comportant plusieurs propriétés, chacune pouvant utiliser plusieurs valeurs. Pour accepter les entités de ce type, l'index doit inclure une entrée pour chaque combinaison possible de valeurs de propriété. Les index personnalisés faisant référence à plusieurs propriétés, chacune avec plusieurs valeurs, peuvent devenir exponentiel de manière combinatoire, nécessitant un grand nombre d'entrées pour une entité ne disposant que d'un nombre relativement réduit de valeurs de propriétés possibles. Ces index exponentiels peuvent considérablement augmenter la taille de l'espace de stockage d'une entité, en raison du grand nombre d'entrées d'index à stocker. Les index exponentiels peuvent également inciter l'entité à dépasser le nombre d'entrées d'index ou la taille limite.

Prenons l'exemple de code suivant :

C#

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore C#.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

Entity task = new Entity()
{
    Key = _db.CreateKeyFactory("Task").CreateKey("sampleTask"),
    ["tags"] = new ArrayValue() { Values = { "fun", "programming", "learn" } },
    ["collaborators"] = new ArrayValue() { Values = { "alice", "bob", "charlie" } },
    ["created"] = DateTime.UtcNow
};

Go

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore Go.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

task := &Task{
	Tags:          []string{"fun", "programming", "learn"},
	Collaborators: []string{"alice", "bob", "charlie"},
	Created:       time.Now(),
}

Java

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore Java.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

Entity task =
    Entity.newBuilder(taskKey)
        .set("tags", "fun", "programming", "learn")
        .set("collaborators", "alice", "bob", "charlie")
        .set("created", Timestamp.now())
        .build();

Node.js

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore Node.js.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

const task = {
  method: 'insert',
  key: datastore.key('Task'),
  data: {
    tags: ['fun', 'programming', 'learn'],
    collaborators: ['alice', 'bob', 'charlie'],
    created: new Date(),
  },
};

PHP

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore PHP.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

$task = $datastore->entity(
    $datastore->key('Task'),
    [
        'tags' => ['fun', 'programming', 'learn'],
        'collaborators' => ['alice', 'bob', 'charlie'],
        'created' => new DateTime(),
    ]
);

Python

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore Python.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement 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(
    {
        "tags": ["fun", "programming", "learn"],
        "collaborators": ["alice", "bob", "charlie"],
        "created": datetime.datetime.now(tz=datetime.timezone.utc),
    }
)

Ruby

Pour savoir comment installer et utiliser la bibliothèque cliente pour Cloud Datastore, consultez la page Bibliothèques clientes Cloud Datastore. Pour plus d'informations, consultez la documentation de référence de l'API Cloud Datastore Ruby.

Pour vous authentifier auprès de Cloud Datastore, configurez les Identifiants par défaut de l'application. Pour en savoir plus, consultez Configurer l'authentification pour un environnement de développement local.

task = datastore.entity "Task" do |t|
  t["tags"] = ["fun", "programming", "learn"]
  t["collaborators"] = ["alice", "bob", "charlie"]
  t["created"] = Time.now
end

GQL

Non applicable

Il crée une entité Task avec trois valeurs pour la propriété tags, trois valeurs pour la propriété collaborators et une propriété created définie à la date du jour. Neuf entrées d'index sont requises, une pour chaque combinaison possible de valeurs de propriété :

('fun', 'alice', NOW())
('fun', 'bob', NOW())
('fun', 'charlie', NOW())

('programming', 'alice', NOW())
('programming', 'bob', NOW())
('programming', 'charlie', NOW())

('learn', 'alice', NOW())
('learn', 'bob', NOW())
('learn', 'charlie', NOW())

Lorsque la même propriété est répétée plusieurs fois, Firestore en mode Datastore peut détecter les index exponentiels et suggérer un autre index. Toutefois, dans tous les autres cas (comme la requête définie dans cet exemple), une base de données en mode Datastore génère un index exponentiel. Dans ce cas, vous pouvez contourner l'index exponentiel en configurant manuellement un index dans le fichier de configuration d'index :

indexes:
- kind: Task
  properties:
  - name: tags
  - name: created
- kind: Task
  properties:
  - name: collaborators
  - name: created

Cela permet de réduire le nombre d'entrées nécessaires à seulement (|tags| * |created| + |collaborators| * |created|), soit six entrées au lieu de neuf :

('fun', NOW())
('programming', NOW())
('learn', NOW())

('alice', NOW())
('bob', NOW())
('charlie', NOW())

Toute opération de type commit qui pourrait atteindre la limite d'entrée d'index ou de taille échouera. Le texte de l'erreur indique quelle limite a été dépassée ("Too many indexed properties" ou "Index entries too large") et quel index personnalisé est à l'origine de l'incident. Si vous créez un index qui dépasse les limites de n'importe quelle entité lors de sa création, les requêtes sur l'index échouent et l'index présente l'état Error dans la console Google Cloud. Pour gérer ces index Error, procédez comme suit :

  1. Supprimez l'index du fichier de configuration d'index (index.yaml).
  2. À l'aide de la Google Cloud CLI, supprimez l'index de la base de données à l'aide de la commande datastore indexes cleanup, comme décrit dans la section Supprimer des index inutilisés.
  3. Soit
    • Reformulez la définition de l'index et les requêtes correspondantes.
    • Supprimez les entités à l'origine de l'index exponentiel.
  4. Replacez l'index dans votre fichier index.yaml.
  5. À l'aide de la Google Cloud CLI, ajoutez l'index à la base de données en exécutant la commande datastore indexes create, comme décrit dans la section Mettre à jour des index.

En utilisant une propriété de liste, vous pouvez éviter les requêtes qui nécessiteraient un index personnalisé, et ainsi éviter les index exponentiels. Comme décrit ci-dessus, cette opération inclut les requêtes avec plusieurs ordres de tri ou les requêtes combinant des filtres d'égalité et d'inégalité.

Index des projections

Les requêtes de projection exigent que toutes les propriétés spécifiées dans la projection soient incluses dans un index. L'émulateur Datastore génère automatiquement les index dont vous avez besoin dans le fichier de configuration de l'index, index.yaml, qui est importé avec votre application.

Une manière de réduire le nombre d'index requis consiste à projeter les mêmes propriétés de façon systématique, même si elles ne sont pas toutes toujours nécessaires. Par exemple, ces requêtes nécessitent deux index distincts :

SELECT priority, percent_complete FROM Task

SELECT priority, percent_complete, created FROM Task

Toutefois, si vous projetez toujours les propriétés priority, percent_complete et created, même lorsque la propriété created n'est pas requise, un seul index suffit.

La conversion d'une requête existante en une requête de projection peut nécessiter la création d'un index si les propriétés de la projection ne sont pas déjà incluses dans une autre partie de la requête. Par exemple, supposons que vous ayez la requête existante suivante :

SELECT * FROM Task
WHERE priority > 1
ORDER BY priority, percent_complete

qui nécessite l'index suivant :

indexes:
- kind: Task
  properties:
  - name: priority
  - name: percent_complete

Si vous convertissez la requête en l'une de ces requêtes de projection,

SELECT created FROM Task
WHERE priority > 1
ORDER BY priority, percent_complete

SELECT priority, percent_complete, created FROM Task
WHERE priority > 1
ORDER BY priority, percent_complete

vous obtenez une nouvelle propriété (created), ce qui entraîne la création d'un index :

indexes:
- kind: Task
  properties:
  - name: priority
  - name: percent_complete
  - name: created

Toutefois,

SELECT priority, percent_complete FROM Task
WHERE priority > 1
ORDER BY priority, percent_complete

ne modifie pas l'index requis, car les propriétés projetées priority et percent_complete étaient déjà incluses dans la requête existante.

Bases de données multiples

Vous pouvez utiliser gcloud firestore pour gérer un seul index en mode Datastore ou utiliser gcloud datastore avec un fichier index.yaml pour gérer tous les index d'une base de données.

gcloud firestore
gcloud firestore indexes composite create --api-scope=datastore-mode-api  --query-scope=QUERY_SCOPE --database=DATABASE_ID
gdoud datastore
gcloud alpha datastore indexes create index.yaml --database=DATABASE_ID

Remplacez les éléments suivants :

  • DATABASE_ID: ID de base de données.
  • QUERY_SCOPE: collection-recursive pour les index ancêtres ou collection-group pour les index non ascendants.