Créer un connecteur de contenu

Un connecteur de contenu est un logiciel permettant de balayer les données d'un dépôt d'entreprise et de les insérer dans une source de données. Google propose les options suivantes pour développer des connecteurs de contenu :

  • Le SDK Content Connector. Cette option est une bonne solution si vous programmez en Java. Le SDK Content Connector est un wrapper pour l'API REST qui accélère la création des connecteurs. Pour créer un connecteur de contenu avec ce SDK, reportez-vous à la section Créer un connecteur de contenu à l'aide du SDK Content Connector.

  • Une API REST de bas niveau ou des bibliothèques d'API. Préférez ces options si vous ne programmez pas en Java, ou si votre base de code est mieux adaptée à une API REST ou à une bibliothèque. Pour créer un connecteur de contenu avec une API REST, reportez-vous à la section Créer un connecteur de contenu à l'aide de l'API REST.

Un connecteur de contenu standard exécute les tâches suivantes :

  1. Lecture et traitement des paramètres de configuration
  2. Extraction de fragments distincts de données indexables, appelées éléments, à partir du dépôt de contenu tiers
  3. Combinaison des listes de contrôle d'accès (LCA), des métadonnées et des contenus dans les éléments indexables
  4. Indexation des éléments dans la source de données Cloud Search
  5. (Facultatif) Écoute des notifications de modification en provenance du dépôt de contenu tiers. Ces notifications sont converties en requêtes d'indexation afin que la source de données Cloud Search soit synchronisée avec le dépôt tiers. Le connecteur exécute cette tâche à condition que le dépôt autorise la détection des modifications.

Créer un connecteur de contenu à l'aide du SDK Content Connector

Les sections suivantes expliquent comment créer un connecteur de contenu à l'aide du SDK Content Connector.

Télécharger et installer le SDK Content Connector

Maven doit être installé avant de procéder à l'installation du SDK Content Connector. Pour installer le SDK Content Connector :

  1. Téléchargez le SDK Content Connector.

  2. Utilisez la ligne de commande pour décompresser le fichier téléchargé. Un répertoire est créé pour le SDK Content Connector.

  3. À partir du répertoire du SDK Content Connector, utilisez les commandes suivantes pour installer chaque partie du SDK :

mvn org.apache.maven.plugins:maven-install-plugin:3.0.0-M1::install-file -DpomFile=parent/pom.xml -Dpackaging=pom -Dfile=parent/pom.xml

mvn org.apache.maven.plugins:maven-install-plugin:3.0.0-M1::install-file -Dfile=lib/google-api-services-cloudsearch-v1-rev0-1.23.0.jar

mvn org.apache.maven.plugins:maven-install-plugin:3.0.0-M1::install-file -Dfile=lib/google-cloudsearch-connector-sdk-v1-0.0.2.jar

mvn org.apache.maven.plugins:maven-install-plugin:3.0.0-M1::install-file -Dfile=google-cloudsearch-indexing-connector-sdk-v1-0.0.2.jar

Configurer des dépendances

Pour utiliser le SDK, vous devez ajouter des dépendances dans le fichier de compilation. Cliquez sur un onglet ci-dessous afin d'afficher les dépendances pour votre environnement de compilation :

Maven

<dependency>
<groupId>com.google.enterprise.cloudsearch</groupId>
<artifactId>google-cloudsearch-indexing-connector-sdk</artifactId>
<version>v1-0.0.2</version>
</dependency>

Gradle

compile group: 'com.google.enterprise.cloudsearch',
        name: 'google-cloudsearch-indexing-connector-sdk',
        version: 'v1-0.0.2'

Créer votre configuration de connecteur

Chaque connecteur dispose d'un fichier de configuration contenant ses paramètres (comme l'ID de votre dépôt), définis sous forme de paires valeur/clé. Par exemple :

api.sourceId=1234567890abcdef
.

Le SDK Google Cloud Search contient plusieurs paramètres de configuration fournis par Google qui sont utilisés par tous les connecteurs. Les paramètres suivants (fournis par Google) sont à déclarer dans votre fichier de configuration :

  • Pour un connecteur de contenu, vous devez déclarer api.sourceId et api.serviceAccountPrivateKeyFile, car ces paramètres identifient l'emplacement de votre dépôt et du fichier contenant la clé privée requise pour y accéder.
  • Pour un connecteur d'identité, vous devez déclarer api.identitySourceId, car ce paramètre identifie l'emplacement de la source d'identité externe. En cas de synchronisation des utilisateurs, déclarez également api.customerId comme ID unique pour le compte G Suite de votre entreprise.

À moins que vous souhaitiez remplacer les valeurs par défaut d'autres paramètres fournis par Google, il est inutile de déclarer ces paramètres dans votre fichier de configuration. Pour plus d'informations sur les paramètres de configuration fournis par Google, concernant la génération de certains ID et de certaines clés, entre autres, reportez-vous à la page Paramètres de configuration fournis par Google.

Vous pouvez également définir des paramètres personnalisés propres au dépôt dans votre fichier de configuration.

Remarque : Le fichier de propriétés des connecteurs n'est soumis à aucune convention d'attribution de noms stricte. Nous vous recommandons cependant de l'enregistrer sous l'extension .properties ou .config.

Transmettre le fichier de configuration au connecteur

Définissez la propriété système config de manière à transmettre le fichier de configuration à votre connecteur. Pour ce faire, utilisez l'argument -D lors du démarrage du connecteur. Par exemple, la commande suivante permet de démarrer le connecteur avec le fichier de configuration MyConfig.properties :

java -classpath myconnector.jar;... -Dconfig=MyConfig.properties MyConnector

Si cet argument n'est pas transmis, le SDK tente d'accéder à un fichier de configuration par défaut nommé connector-config.properties.

Déterminer votre stratégie de balayage

La fonction principale d'un connecteur de contenu consiste à balayer un dépôt et à en indexer les données. C'est pourquoi vous devez mettre en place une stratégie de balayage adaptée à la taille des données et à leur disposition dans votre dépôt. Deux options s'offrent à vous : soit vous élaborez votre propre stratégie, soit vous en choisissez une parmi celles proposées dans le SDK.

Stratégie de balayage complet

La stratégie de balayage complet consiste à analyser le dépôt entier et à en indexer automatiquement chaque élément. Cette stratégie est couramment employée avec les dépôts de petite taille, lorsque l'entreprise peut se permettre cette opération à chaque indexation.

Cette stratégie de balayage est indiquée pour les dépôts de petite taille, renfermant principalement des données statiques non hiérarchisées. Elle convient également lorsque la détection des modifications est complexe ou incompatible avec le dépôt.

Stratégie de balayage de liste

La stratégie de balayage de liste consiste à analyser le dépôt entier, y compris les nœuds enfants, tout en déterminant l'état de chaque élément. Puis, lors d'une seconde passe, le connecteur n'indexe que les éléments nouveaux ou mis à jour depuis la dernière indexation. Cette stratégie est fréquemment utilisée pour actualiser progressivement un index existant (et éviter ainsi un balayage complet à chaque mise à jour de l'index).

Cette stratégie de balayage convient dans les situations suivantes : la détection des modifications est complexe ou incompatible avec le dépôt, les données ne sont pas hiérarchisées ou vous travaillez avec des ensembles de données très volumineux.

Stratégie de balayage de graphe

La stratégie de balayage de graphe consiste à analyser l'intégralité du nœud parent en déterminant l'état de chaque élément. Puis, lors d'une seconde passe, le connecteur n'indexe que les éléments du nœud racine qui sont nouveaux ou ont été mis à jour depuis la dernière indexation. Il traite enfin les ID des éléments enfants, puis indexe les éléments nouveaux ou mis à jour au niveau de ces nœuds. Il procède ainsi de manière récursive avec chaque nœud enfant jusqu'à ce que tous les éléments aient été traités. Cette stratégie de balayage est généralement retenue avec les dépôts hiérarchiques pour lesquels il est difficile d'établir une liste exhaustive des ID.

Cette stratégie convient pour explorer des données hiérarchisées, comme une série de répertoires ou de pages Web.

Chacune de ces stratégies de balayage est mise en place au moyen d'un modèle de classe de connecteur disponible dans le SDK. Bien que vous puissiez mettre en œuvre votre propre stratégie de balayage, ces modèles accélèrent considérablement le développement de votre connecteur. Pour créer un connecteur à partir d'un modèle, accédez à la section correspondant à votre stratégie de balayage :

Créer un connecteur de balayage complet à partir d'un modèle de classe

Cette section fait référence aux extraits de code de l'exemple FullTraversalSample.

Ajouter le point d'entrée du connecteur

Le point d'entrée d'un connecteur est la méthode main(). La fonction principale de cette méthode consiste à créer une instance de la classe Application et à appeler sa méthode start() pour exécuter le connecteur.

Avant d'appeler application.start(), utilisez la classe IndexingApplication.Builder pour instancier le modèle FullTraversalConnector. Le modèle FullTraversalConnector accepte un objet Repository dont vous utiliserez les méthodes. L'extrait de code suivant montre comment mettre en œuvre la méthode main() :

FullTraversalSample.java
/**
 * This sample connector uses the Cloud Search SDK template class for a full
 * traversal connector.
 *
 * @param args program command line arguments
 * @throws InterruptedException thrown if an abort is issued during initialization
 */
public static void main(String[] args) throws InterruptedException {
  Repository repository = new SampleRepository();
  IndexingConnector connector = new FullTraversalConnector(repository);
  IndexingApplication application = new IndexingApplication.Builder(connector, args).build();
  application.start();
}

En coulisses, le SDK appelle la méthode initConfig(), après que la méthode main() de votre connecteur a appelé Application.build. La méthode initConfig() accomplit les tâches suivantes :

  1. Appel de la méthode Configuation.isInitialized() pour confirmer que l'objet Configuration n'a pas été initialisé
  2. Initialisation d'un objet Configuration avec les paires valeur/clé fournies par Google. Chaque paire valeur/clé est stockée dans un objet ConfigValue à l'intérieur de l'objet Configuration.

Ajouter l'interface Repository

L'objet Repository n'a qu'une fonction, qui consiste à balayer les éléments du dépôt et à les indexer. Lorsque vous utilisez un modèle, il vous suffit de remplacer certaines méthodes dans l'interface Repository pour créer un connecteur de contenu. Ces méthodes dépendent de la stratégie de balayage et du modèle employés. Pour le modèle FullTraversalConnector, par exemple, vous devez remplacer les méthodes suivantes :

  • init(). Pour configurer et initialiser un dépôt de données, remplacez la méthode init().

  • getAllDocs(). Pour balayer et indexer tous les éléments du dépôt de données, remplacez la méthode getAllDocs(). Celle-ci est appelée une fois lors de chaque balayage planifié (tel que défini par votre configuration).

  • (Facultatif) getChanges(). Si votre dépôt accepte la détection des modifications, remplacez la méthode getChanges(). Celle-ci est appelée une fois lors de chaque balayage incrémentiel planifié (tel que défini par votre configuration) afin d'extraire les éléments modifiés et de les indexer.

  • (Facultatif) close(). Si vous devez procéder au nettoyage du dépôt, remplacez la méthode close(). Celle-ci est appelée une fois lors de l'arrêt du connecteur.

Chaque méthode de l'objet Repository renvoie un objet ApiOperation. C'est grâce à l'objet ApiOperation que le dépôt est effectivement indexé, via un ou plusieurs appels de la méthode IndexingService.indexItem().

Récupérer les paramètres de configuration personnalisés

Lorsque vous réalisez la configuration de votre connecteur, vous devez récupérer les éventuels paramètres personnalisés contenus dans l'objet Configuration. Cette tâche est généralement effectuée dans une méthode init() de la classe Repository.

La classe Configuration comprend plusieurs méthodes qui permettent d'obtenir différents types de données à partir d'une configuration. Chaque méthode renvoie un objet ConfigValue. Pour récupérer la valeur réelle, utilisez ensuite la méthode get() de l'objet ConfigValue. L'extrait de code suivant (issu du modèle FullTraversalSample) montre comment récupérer une valeur entière personnalisée à partir d'un objet Configuration :

FullTraversalSample.java
@Override
public void init(RepositoryContext context) {
  log.info("Initializing repository");
  numberOfDocuments = Configuration.getInteger("sample.documentCount", 10).get();
}

Pour récupérer et analyser un paramètre contenant plusieurs valeurs, utilisez l'un des analyseurs de type de la classe Configuration, qui permettent d'analyser les données par fragments distincts. L'extrait de code suivant (issu du connecteur du tutoriel) permet d'obtenir la liste des noms de dépôts GitHub grâce à la méthode getMultiValue :

GithubRepository.java
ConfigValue<List<String>> repos = Configuration.getMultiValue(
    "github.repos",
    Collections.emptyList(),
    Configuration.STRING_PARSER);

Effectuer un balayage complet

Remplacez la méthode getAllDocs() pour réaliser un balayage complet et indexer le dépôt. La méthode getAllDocs() accepte un point de contrôle qui permet de reprendre l'indexation à partir d'un élément donné si le processus est interrompu. Pour chaque élément du dépôt, vous accomplirez les tâches suivantes dans la méthode getAllDocs() :

  1. Définissez les autorisations.
  2. Définissez les métadonnées de l'élément que vous indexez.
  3. Combinez les métadonnées et l'élément dans un objet RepositoryDoc indexable.
  4. Empaquetez chaque élément indexable dans un itérateur renvoyé par la méthode getAllDocs(). getAllDocs() renvoie en fait un CheckpointCloseableIterable, qui correspond à une itération d'objets ApiOperation, chaque objet représentant une requête d'API sur un objet RepositoryDoc (par exemple, une requête d'indexation des éléments).

Si l'ensemble d'éléments est trop volumineux pour être traité via un seul appel, insérez un point de contrôle et définissez hasMore (true) pour indiquer qu'il reste des éléments à indexer.

Définir les autorisations pour un élément

Votre dépôt s'appuie sur une liste de contrôle d'accès (LCA) pour identifier les utilisateurs ou les groupes ayant accès à un élément. Une LCA est une liste d'ID désignant ces groupes ou ces utilisateurs.

Pour que les utilisateurs ayant accès à un élément soient les seuls à pouvoir le voir dans un résultat de recherche, vous devez dupliquer la LCA correspondante dans la source de données. Par conséquent, cette liste doit être incluse lors de l'indexation de l'élément afin que Google Cloud Search dispose des informations nécessaires pour accorder le niveau d'accès qui convient.

Le SDK Content Connector propose un vaste choix de classes et de méthodes pour modéliser les LCA de la plupart des dépôts. Pour chaque élément de votre dépôt, il vous faut analyser la LCA associée et créer une liste correspondante pour Google Cloud Search au moment d'indexer l'élément. Il se peut que la LCA de votre dépôt repose sur des concepts qui compliquent la tâche de modélisation, comme l'héritage de liste. Consultez les informations sur les LCA de Google Cloud Search pour en savoir plus.

Remarque : L'API Cloud Search Indexing accepte les LCA à domaine unique, mais pas les LCA interdomaines. Pour l'essentiel, vous utiliserez la classe Acl.Builder pour définir l'accès à chaque élément via une LCA. L'extrait de code suivant, tiré de l'exemple de balayage complet, permet à tous les utilisateurs ou "comptes principaux" (getCustomerPrincipal()) d'être des "lecteurs" de tous les éléments (.setReaders()) dans le cadre d'une recherche.

FullTraversalSample.java
// Make the document publicly readable within the domain
Acl acl = new Acl.Builder()
    .setReaders(Collections.singletonList(Acl.getCustomerPrincipal()))
    .build();

Vous devez savoir comment fonctionnent les LCA afin de les modéliser correctement pour la source de données. Il se peut que les fichiers à indexer soient stockés dans un système de fichiers basé sur un modèle d'héritage, dans lequel les dossiers enfants héritent des autorisations des dossiers parents. La modélisation du mécanisme d'héritage des LCA nécessite des connaissances supplémentaires. Pour en savoir plus, consultez les informations sur les LCA de Google Cloud Search.

Définir les métadonnées d'un élément

Les métadonnées sont stockées dans un objet Item. La création d'un objet Item nécessite un minimum d'informations : un ID de chaîne unique ainsi que le type, la LCA, l'URL et la version de l'élément. L'extrait de code suivant indique comment créer un objet Item avec la classe auxiliaire IndexingItemBuilder.

FullTraversalSample.java
// Url is required. Use google.com as a placeholder for this sample.
String viewUrl = "https://www.google.com";

// Version is required, set to current timestamp.
byte[] version = Longs.toByteArray(System.currentTimeMillis());

// Using the SDK item builder class to create the document with appropriate attributes
// (this can be expanded to include metadata fields etc.)
Item item = IndexingItemBuilder.fromConfiguration(Integer.toString(id))
    .setItemType(IndexingItemBuilder.ItemType.CONTENT_ITEM)
    .setAcl(acl)
    .setSourceRepositoryUrl(IndexingItemBuilder.FieldOrValue.withValue(viewUrl))
    .setVersion(version)
    .build();

Créer l'élément indexable

Après avoir défini les métadonnées de l'élément, vous pouvez créer l'élément indexable avec la classe RepositoryDoc.Builder. L'exemple suivant vous montre la marche à suivre.

FullTraversalSample.java
// For this sample, content is just plain text
String content = String.format("Hello world from sample doc %d", id);
ByteArrayContent byteContent = ByteArrayContent.fromString("text/plain", content);

// Create the fully formed document
RepositoryDoc doc = new RepositoryDoc.Builder()
    .setItem(item)
    .setContent(byteContent, IndexingService.ContentFormat.TEXT)
    .build();

Un RepositoryDoc est un type d'objet ApiOperation qui exécute la requête IndexingService.indexItem().

Vous pouvez également vous servir de la méthode setRequestMode() de la classe RepositoryDoc.Builder pour définir le mode de requête d'indexation (ASYNCHRONOUS ou SYNCHRONOUS) :

ASYNCHRONOUS
Le mode asynchrone augmente la latence entre l'indexation et la diffusion des éléments, mais autorise un débit supérieur pour les requêtes d'indexation. Il est recommandé pour l'indexation initiale (le remplissage) du dépôt complet.
SYNCHRONOUS
Le mode synchrone diminue la latence entre l'indexation et la diffusion des éléments, mais autorise un débit moindre. Il est recommandé pour l'indexation des mises à jour et des modifications apportées au dépôt. Si vous n'indiquez pas de mode de requête, la valeur SYNCHRONOUS est attribuée par défaut.

Empaqueter chaque élément indexable dans un itérateur

La méthode getAllDocs() renvoie un Iterator, en particulier un CheckpointCloseableIterable, d'objets RepositoryDoc. Vous pouvez construire et renvoyer un itérateur à l'aide de la classe CheckpointClosableIterableImpl.Builder. L'extrait de code suivant indique la marche à suivre.

FullTraversalSample.java
CheckpointCloseableIterable<ApiOperation> iterator =
  new CheckpointCloseableIterableImpl.Builder<>(allDocs).build();

Le SDK exécute chaque appel d'indexation figurant dans l'itérateur.

Étapes suivantes

Voici quelques étapes supplémentaires que vous pouvez effectuer :

Créer un connecteur de balayage de liste à partir d'un modèle de classe

Le connecteur de balayage de liste place les ID d'élément dans une file d'attente d'indexation Cloud Search, puis les récupère un par un en vue d'indexer les éléments. Cette file d'attente permet de conserver l'ID de chaque élément du dépôt ainsi que la valeur de hachage associée (le cas échéant). Google Cloud Search gère les files d'attente et compare leur contenu afin de déterminer l'état des éléments (si un élément a été supprimé du dépôt, par exemple). Pour en savoir plus sur ces files d'attente, consultez l'article File d'attente d'indexation Cloud Search.

Cette section fait référence aux extraits de code de l'exemple ListTraversalSample.

Ajouter le point d'entrée du connecteur

Le point d'entrée d'un connecteur est la méthode main(). La fonction principale de cette méthode consiste à créer une instance de la classe Application et à appeler sa méthode start() pour exécuter le connecteur.

Avant d'appeler application.start(), utilisez la classe IndexingApplication.Builder pour instancier le modèle ListingConnector. Le modèle ListingConnector accepte un objet Repository dont vous utiliserez les méthodes. L'extrait de code suivant montre comment instancier le modèle ListingConnector et l'objet Repository associé :

ListTraversalSample.java
/**
 * This sample connector uses the Cloud Search SDK template class for a
 * list traversal connector.
 *
 * @param args program command line arguments
 * @throws InterruptedException thrown if an abort is issued during initialization
 */
public static void main(String[] args) throws InterruptedException {
  Repository repository = new SampleRepository();
  IndexingConnector connector = new ListingConnector(repository);
  IndexingApplication application = new IndexingApplication.Builder(connector, args).build();
  application.start();
}

En coulisses, le SDK appelle la méthode initConfig(), après que la méthode main() de votre connecteur a appelé Application.build. La méthode initConfig() accomplit les tâches suivantes :

  1. Appel de la méthode Configuation.isInitialized() pour confirmer que l'objet Configuration n'a pas été initialisé
  2. Initialisation d'un objet Configuration avec les paires valeur/clé fournies par Google. Chaque paire valeur/clé est stockée dans un objet ConfigValue à l'intérieur de l'objet Configuration.

Ajouter l'interface Repository

L'objet Repository n'a qu'une fonction, qui consiste à balayer les éléments du dépôt et à les indexer. Lorsque vous utilisez un modèle, il vous suffit de remplacer certaines méthodes dans l'interface Repository pour créer un connecteur de contenu. Ces méthodes dépendent de la stratégie de balayage et du modèle employés. Pour le modèle ListingConnector, par exemple, vous devez remplacer les méthodes suivantes :

  • init(). Pour configurer et initialiser un dépôt de données, remplacez la méthode init().

  • getIds(). Pour récupérer les ID et les valeurs de hachage de l'ensemble des enregistrements du dépôt, remplacez la méthode getIds().

  • getDoc(). Pour ajouter des éléments à l'index, ou mettre à jour, modifier ou supprimer des éléments spécifiques, remplacez la méthode getDoc().

  • (Facultatif) getChanges(). Si votre dépôt accepte la détection des modifications, remplacez la méthode getChanges(). Celle-ci est appelée une fois lors de chaque balayage incrémentiel planifié (tel que défini par votre configuration) afin d'extraire les éléments modifiés et de les indexer.

  • (Facultatif) close(). Si vous devez procéder au nettoyage du dépôt, remplacez la méthode close(). Celle-ci est appelée une fois lors de l'arrêt du connecteur.

Chaque méthode de l'objet Repository renvoie un objet ApiOperation. C'est grâce à l'objet ApiOperation que le dépôt est effectivement indexé, via un ou plusieurs appels de la méthode IndexingService.indexItem().

Récupérer les paramètres de configuration personnalisés

Lorsque vous réalisez la configuration de votre connecteur, vous devez récupérer les éventuels paramètres personnalisés contenus dans l'objet Configuration. Cette tâche est généralement effectuée dans une méthode init() de la classe Repository.

La classe Configuration comprend plusieurs méthodes qui permettent d'obtenir différents types de données à partir d'une configuration. Chaque méthode renvoie un objet ConfigValue. Pour récupérer la valeur réelle, utilisez ensuite la méthode get() de l'objet ConfigValue. L'extrait de code suivant (issu du modèle FullTraversalSample) montre comment récupérer une valeur entière personnalisée à partir d'un objet Configuration :

FullTraversalSample.java
@Override
public void init(RepositoryContext context) {
  log.info("Initializing repository");
  numberOfDocuments = Configuration.getInteger("sample.documentCount", 10).get();
}

Pour récupérer et analyser un paramètre contenant plusieurs valeurs, utilisez l'un des analyseurs de type de la classe Configuration, qui permettent d'analyser les données par fragments distincts. L'extrait de code suivant (issu du connecteur du tutoriel) permet d'obtenir la liste des noms de dépôts GitHub grâce à la méthode getMultiValue :

GithubRepository.java
ConfigValue<List<String>> repos = Configuration.getMultiValue(
    "github.repos",
    Collections.emptyList(),
    Configuration.STRING_PARSER);

Effectuer un balayage de liste

Remplacez la méthode getIds() pour récupérer les ID et les valeurs de hachage de l'ensemble des enregistrements du dépôt. La méthode getIds() accepte un point de contrôle qui permet de reprendre l'indexation à partir d'un élément donné si le processus est interrompu.

Remplacez ensuite la méthode getDoc() afin de traiter chaque élément de la file d'attente d'indexation Cloud Search.

Transmettre les ID et valeurs de hachage des éléments

Remplacez getIds() pour récupérer les ID des éléments et les valeurs de hachage de contenu associées dans le dépôt. Les paires ID/valeur de hachage sont ensuite empaquetées dans une requête de transmission et placées dans la file d'attente d'indexation Cloud Search. Les ID des éléments racines ou parents sont généralement transmis en premier, suivis des ID des éléments enfants, jusqu'à ce que l'arborescence ait été entièrement traitée.

La méthode getIds() accepte un point de contrôle représentant le dernier élément à indexer. Le point de contrôle permet de reprendre l'indexation à partir d'un élément donné si le processus est interrompu. Pour chaque élément du dépôt, vous accomplirez les tâches suivantes dans la méthode getIds() :

  • Récupérez l'ID et la valeur de hachage associée (le cas échéant) pour chaque élément du dépôt.
  • Empaquetez chaque paire ID/valeur de hachage dans un objet PushItems.
  • Combinez chaque objet PushItems dans un itérateur renvoyé par la méthode getIds(). getIds() renvoie en fait un CheckpointCloseableIterable, qui correspond à une itération d'objets ApiOperation, chaque objet représentant une requête d'API sur un objet RepositoryDoc (par exemple, une requête de placement des éléments dans la file d'attente).

L'extrait de code suivant montre comment récupérer l'ID et la valeur de hachage de chaque élément, puis insérer ces informations dans un objet PushItem. Un objet PushItems correspond à une requête ApiOperation visant à placer un élément dans la file d'attente d'indexation Cloud Search.

ListTraversalSample.java
PushItems.Builder allIds = new PushItems.Builder();
for (Map.Entry<Integer, Long> entry : this.documents.entrySet()) {
  String documentId = Integer.toString(entry.getKey());
  String hash = this.calculateMetadataHash(entry.getKey());
  PushItem item = new PushItem().setMetadataHash(hash);
  log.info("Pushing " + documentId);
  allIds.addPushItem(documentId, item);
}

L'extrait de code suivant montre comment utiliser la classe PushItems.Builder pour empaqueter les ID et les valeurs de hachage dans un seul objet ApiOperation de transmission.

ListTraversalSample.java
ApiOperation pushOperation = allIds.build();
CheckpointCloseableIterable<ApiOperation> iterator =
  new CheckpointCloseableIterableImpl.Builder<>(
      Collections.singletonList(pushOperation))
  .build();
return iterator;

Les éléments sont placés dans la file d'attente d'indexation Cloud Search en vue d'être traités.

Récupérer et traiter chaque élément

Remplacez la méthode getDoc() afin de traiter chaque élément de la file d'attente d'indexation Cloud Search. Un élément peut avoir été ajouté dans le dépôt source, modifié (ou pas) ou bien avoir été supprimé. Récupérez et indexez chaque élément nouveau ou modifié. Retirez de l'index ceux qui n'existent plus dans le dépôt source.

La méthode getDoc() accepte un élément de la file d'attente d'indexation Google Cloud Search. Pour chaque élément de la file d'attente, vous accomplirez les tâches suivantes dans la méthode getDoc() :

  1. Vérifiez si l'élément figure dans le dépôt, d'après son ID dans la file d'attente d'indexation Google Cloud Search. Si ce n'est pas le cas, supprimez-le de l'index.

  2. Interrogez l'index pour connaître l'état de l'élément. Si celui-ci n'a pas changé (état ACCEPTED), ne faites rien.

  3. Pour les éléments d'index nouveaux ou modifiés, procédez comme suit :

    1. Définissez les autorisations.
    2. Définissez les métadonnées de l'élément que vous indexez.
    3. Combinez les métadonnées et l'élément dans un objet RepositoryDoc indexable.
    4. Renvoyez l'objet RepositoryDoc.

Traiter les éléments supprimés

L'extrait de code suivant indique comment déterminer si un élément figure dans le dépôt et, s'il ne s'y trouve pas, comment le supprimer.

ListTraversalSample.java
String resourceName = item.getName();
int documentId = Integer.parseInt(resourceName);

if (!documents.containsKey(documentId)) {
  // Document no longer exists -- delete it
  log.info(() -> String.format("Deleting document %s", item.getName()));
  return ApiOperations.deleteItem(resourceName);
}

documents est une structure de données représentant le dépôt. Si documentID ne figure pas dans documents, renvoyez APIOperations.deleteItem(resourceName) pour supprimer l'élément de l'index.

Traiter les éléments non modifiés

L'extrait de code suivant indique comment connaître l'état d'un élément dans la file d'attente d'indexation Google Cloud Search et comment traiter un élément non modifié.

ListTraversalSample.java
String currentHash = this.calculateMetadataHash(documentId);
if (this.canSkipIndexing(item, currentHash)) {
  // Document neither modified nor deleted, ack the push
  log.info(() -> String.format("Document %s not modified", item.getName()));
  PushItem pushItem = new PushItem().setType("NOT_MODIFIED");
  return new PushItems.Builder().addPushItem(resourceName, pushItem).build();
}

Pour savoir si un élément a été modifié ou non, vérifiez son état ainsi que les autres métadonnées pouvant signaler une modification. Dans l'exemple, le hachage des métadonnées permet de déterminer si l'élément a été modifié.

ListTraversalSample.java
/**
 * Checks to see if an item is already up to date
 *
 * @param previousItem Polled item
 * @param currentHash  Metadata hash of the current github object
 * @return PushItem operation
 */
private boolean canSkipIndexing(Item previousItem, String currentHash) {
  if (previousItem.getStatus() == null || previousItem.getMetadata() == null) {
    return false;
  }
  String status = previousItem.getStatus().getCode();
  String previousHash = previousItem.getMetadata().getHash();
  return "ACCEPTED".equals(status)
      && previousHash != null
      && previousHash.equals(currentHash);
}

Définir les autorisations pour un élément

Votre dépôt s'appuie sur une liste de contrôle d'accès (LCA) pour identifier les utilisateurs ou les groupes ayant accès à un élément. Une LCA est une liste d'ID désignant ces groupes ou ces utilisateurs.

Pour que les utilisateurs ayant accès à un élément soient les seuls à pouvoir le voir dans un résultat de recherche, vous devez dupliquer la LCA correspondante dans la source de données. Par conséquent, cette liste doit être incluse lors de l'indexation de l'élément afin que Google Cloud Search dispose des informations nécessaires pour accorder le niveau d'accès qui convient.

Le SDK Content Connector propose un vaste choix de classes et de méthodes pour modéliser les LCA de la plupart des dépôts. Pour chaque élément de votre dépôt, il vous faut analyser la LCA associée et créer une liste correspondante pour Google Cloud Search au moment d'indexer l'élément. Il se peut que la LCA de votre dépôt repose sur des concepts qui compliquent la tâche de modélisation, comme l'héritage de liste. Consultez les informations sur les LCA de Google Cloud Search pour en savoir plus.

Remarque : L'API Cloud Search Indexing accepte les LCA à domaine unique, mais pas les LCA interdomaines. Pour l'essentiel, vous utiliserez la classe Acl.Builder pour définir l'accès à chaque élément via une LCA. L'extrait de code suivant, tiré de l'exemple de balayage complet, permet à tous les utilisateurs ou "comptes principaux" (getCustomerPrincipal()) d'être des "lecteurs" de tous les éléments (.setReaders()) dans le cadre d'une recherche.

FullTraversalSample.java
// Make the document publicly readable within the domain
Acl acl = new Acl.Builder()
    .setReaders(Collections.singletonList(Acl.getCustomerPrincipal()))
    .build();

Vous devez savoir comment fonctionnent les LCA afin de les modéliser correctement pour la source de données. Il se peut que les fichiers à indexer soient stockés dans un système de fichiers basé sur un modèle d'héritage, dans lequel les dossiers enfants héritent des autorisations des dossiers parents. La modélisation du mécanisme d'héritage des LCA nécessite des connaissances supplémentaires. Pour en savoir plus, consultez les informations sur les LCA de Google Cloud Search.

Définir les métadonnées d'un élément

Les métadonnées sont stockées dans un objet Item. La création d'un objet Item nécessite un minimum d'informations : un ID de chaîne unique ainsi que le type, la LCA, l'URL et la version de l'élément. L'extrait de code suivant indique comment créer un objet Item avec la classe auxiliaire IndexingItemBuilder.

ListTraversalSample.java
// Url is required. Use google.com as a placeholder for this sample.
String viewUrl = "https://www.google.com";

// Version is required, set to current timestamp.
byte[] version = Longs.toByteArray(System.currentTimeMillis());

// Set metadata hash so queue can detect changes
String metadataHash = this.calculateMetadataHash(documentId);

// Using the SDK item builder class to create the document with
// appropriate attributes. This can be expanded to include metadata
// fields etc.
Item item = IndexingItemBuilder.fromConfiguration(Integer.toString(documentId))
    .setItemType(IndexingItemBuilder.ItemType.CONTENT_ITEM)
    .setAcl(acl)
    .setSourceRepositoryUrl(IndexingItemBuilder.FieldOrValue.withValue(viewUrl))
    .setVersion(version)
    .setHash(metadataHash)
    .build();

Créer un élément indexable

Après avoir défini les métadonnées de l'élément, vous pouvez créer l'élément indexable avec la classe RepositoryDoc.Builder. L'exemple suivant vous montre la marche à suivre.

ListTraversalSample.java
// For this sample, content is just plain text
String content = String.format("Hello world from sample doc %d", documentId);
ByteArrayContent byteContent = ByteArrayContent.fromString("text/plain", content);

// Create the fully formed document
RepositoryDoc doc = new RepositoryDoc.Builder()
    .setItem(item)
    .setContent(byteContent, IndexingService.ContentFormat.TEXT)
    .build();

Un RepositoryDoc est un type d'objet ApiOperation qui exécute la requête IndexingService.indexItem().

Vous pouvez également vous servir de la méthode setRequestMode() de la classe RepositoryDoc.Builder pour définir le mode de requête d'indexation (ASYNCHRONOUS ou SYNCHRONOUS) :

ASYNCHRONOUS
Le mode asynchrone augmente la latence entre l'indexation et la diffusion des éléments, mais autorise un débit supérieur pour les requêtes d'indexation. Il est recommandé pour l'indexation initiale (le remplissage) du dépôt complet.
SYNCHRONOUS
Le mode synchrone diminue la latence entre l'indexation et la diffusion des éléments, mais autorise un débit moindre. Il est recommandé pour l'indexation des mises à jour et des modifications apportées au dépôt. Si vous n'indiquez pas de mode de requête, la valeur SYNCHRONOUS est attribuée par défaut.

Étapes suivantes

Voici quelques étapes supplémentaires que vous pouvez effectuer :

Créer un connecteur de balayage de graphe à partir d'un modèle de classe

Le connecteur de balayage de graphe place les ID d'élément dans une file d'attente d'indexation Cloud Search, puis les récupère un par un en vue d'indexer les éléments. Cette file d'attente permet de conserver l'ID de chaque élément du dépôt ainsi que la valeur de hachage associée (le cas échéant). Google Cloud Search gère les files d'attente et compare leur contenu afin de déterminer l'état des éléments (si un élément a été supprimé du dépôt, par exemple). Pour en savoir plus sur ces files d'attente, consultez l'article File d'attente d'indexation Cloud Search.

Pendant l'indexation, le contenu des éléments est récupéré dans le dépôt de données et les ID des éléments enfants sont placés dans la file d'attente. Le connecteur procède ainsi de manière récursive avec chaque ID d'élément parent et enfant jusqu'à ce que tous les éléments aient été traités.

Cette section fait référence aux extraits de code de l'exemple GraphTraversalSample.

Ajouter le point d'entrée du connecteur

Le point d'entrée d'un connecteur est la méthode main(). La fonction principale de cette méthode consiste à créer une instance de la classe Application et à appeler sa méthode start() pour exécuter le connecteur.

Avant d'appeler application.start(), utilisez la classe IndexingApplication.Builder pour instancier le modèle ListingConnector. Le modèle ListingConnector accepte un objet Repository dont vous utiliserez les méthodes.

L'extrait de code suivant montre comment instancier le modèle ListingConnector et l'objet Repository associé :

GraphTraversalSample.java
/**
 * This sample connector uses the Cloud Search SDK template class for a graph
 * traversal connector.
 *
 * @param args program command line arguments
 * @throws InterruptedException thrown if an abort is issued during initialization
 */
public static void main(String[] args) throws InterruptedException {
  Repository repository = new SampleRepository();
  IndexingConnector connector = new ListingConnector(repository);
  IndexingApplication application = new IndexingApplication.Builder(connector, args).build();
  application.start();
}

En coulisses, le SDK appelle la méthode initConfig(), après que la méthode main() de votre connecteur a appelé Application.build. La méthode initConfig() accomplit les tâches suivantes :

  1. Appel de la méthode Configuation.isInitialized() pour confirmer que l'objet Configuration n'a pas été initialisé
  2. Initialisation d'un objet Configuration avec les paires valeur/clé fournies par Google. Chaque paire valeur/clé est stockée dans un objet ConfigValue à l'intérieur de l'objet Configuration.

Ajouter l'interface Repository

L'objet Repository n'a qu'une fonction, qui consiste à balayer les éléments du dépôt et à les indexer. Lorsque vous utilisez un modèle, il vous suffit de remplacer certaines méthodes dans l'interface Repository pour créer un connecteur de contenu. Ces méthodes dépendent de la stratégie de balayage et du modèle employés. Pour le modèle ListingConnector, par exemple, vous remplacerez les méthodes suivantes :

  • init(). Pour configurer et initialiser un dépôt de données, remplacez la méthode init().

  • getIds(). Pour récupérer les ID et les valeurs de hachage de l'ensemble des enregistrements du dépôt, remplacez la méthode getIds().

  • getDoc(). Pour ajouter des éléments à l'index, ou mettre à jour, modifier ou supprimer des éléments spécifiques, remplacez la méthode getDoc().

  • (Facultatif) getChanges(). Si votre dépôt accepte la détection des modifications, remplacez la méthode getChanges(). Celle-ci est appelée une fois lors de chaque balayage incrémentiel planifié (tel que défini par votre configuration) afin d'extraire les éléments modifiés et de les indexer.

  • (Facultatif) close(). Si vous devez procéder au nettoyage du dépôt, remplacez la méthode close(). Celle-ci est appelée une fois lors de l'arrêt du connecteur.

Chaque méthode de l'objet Repository renvoie un objet ApiOperation. C'est grâce à l'objet ApiOperation que le dépôt est effectivement indexé, via un ou plusieurs appels de la méthode IndexingService.indexItem().

Récupérer les paramètres de configuration personnalisés

Lorsque vous réalisez la configuration de votre connecteur, vous devez récupérer les éventuels paramètres personnalisés contenus dans l'objet Configuration. Cette tâche est généralement effectuée dans une méthode init() de la classe Repository.

La classe Configuration comprend plusieurs méthodes qui permettent d'obtenir différents types de données à partir d'une configuration. Chaque méthode renvoie un objet ConfigValue. Pour récupérer la valeur réelle, utilisez ensuite la méthode get() de l'objet ConfigValue. L'extrait de code suivant (issu du modèle FullTraversalSample) montre comment récupérer une valeur entière personnalisée à partir d'un objet Configuration :

FullTraversalSample.java
@Override
public void init(RepositoryContext context) {
  log.info("Initializing repository");
  numberOfDocuments = Configuration.getInteger("sample.documentCount", 10).get();
}

Pour récupérer et analyser un paramètre contenant plusieurs valeurs, utilisez l'un des analyseurs de type de la classe Configuration, qui permettent d'analyser les données par fragments distincts. L'extrait de code suivant (issu du connecteur du tutoriel) permet d'obtenir la liste des noms de dépôts GitHub grâce à la méthode getMultiValue :

GithubRepository.java
ConfigValue<List<String>> repos = Configuration.getMultiValue(
    "github.repos",
    Collections.emptyList(),
    Configuration.STRING_PARSER);

Effectuer un balayage de graphe

Remplacez la méthode getIds() pour récupérer les ID et les valeurs de hachage de l'ensemble des enregistrements du dépôt. La méthode getIds() accepte un point de contrôle qui permet de reprendre l'indexation à partir d'un élément donné si le processus est interrompu.

Remplacez ensuite la méthode getDoc() afin de traiter chaque élément de la file d'attente d'indexation Cloud Search.

Transmettre les ID et valeurs de hachage des éléments

Remplacez getIds() pour récupérer les ID des éléments et les valeurs de hachage de contenu associées dans le dépôt. Les paires ID/valeur de hachage sont ensuite empaquetées dans une requête de transmission et placées dans la file d'attente d'indexation Cloud Search. Les ID des éléments racines ou parents sont généralement transmis en premier, suivis des ID des éléments enfants, jusqu'à ce que l'arborescence ait été entièrement traitée.

La méthode getIds() accepte un point de contrôle représentant le dernier élément à indexer. Le point de contrôle permet de reprendre l'indexation à partir d'un élément donné si le processus est interrompu. Pour chaque élément du dépôt, vous accomplirez les tâches suivantes dans la méthode getIds() :

  • Récupérez l'ID et la valeur de hachage associée (le cas échéant) pour chaque élément du dépôt.
  • Empaquetez chaque paire ID/valeur de hachage dans un objet PushItems.
  • Combinez chaque objet PushItems dans un itérateur renvoyé par la méthode getIds(). getIds() renvoie en fait un CheckpointCloseableIterable, qui correspond à une itération d'objets ApiOperation, chaque objet représentant une requête d'API sur un objet RepositoryDoc (par exemple, une requête de placement des éléments dans la file d'attente).

L'extrait de code suivant montre comment récupérer l'ID et la valeur de hachage de chaque élément, puis insérer ces informations dans un objet PushItem. Un objet PushItems correspond à une requête ApiOperation visant à placer un élément dans la file d'attente d'indexation Cloud Search.

GraphTraversalSample.java
PushItems.Builder allIds = new PushItems.Builder();
PushItem item = new PushItem();
allIds.addPushItem("root", item);

L'extrait de code suivant montre comment utiliser la classe PushItems.Builder pour empaqueter les ID et les valeurs de hachage dans un seul objet ApiOperation de transmission.

GraphTraversalSample.java
ApiOperation pushOperation = allIds.build();
CheckpointCloseableIterable<ApiOperation> iterator =
  new CheckpointCloseableIterableImpl.Builder<>(
      Collections.singletonList(pushOperation))
  .build();

Les éléments sont placés dans la file d'attente d'indexation Cloud Search en vue d'être traités.

Récupérer et traiter chaque élément

Remplacez la méthode getDoc() afin de traiter chaque élément de la file d'attente d'indexation Cloud Search. Un élément peut avoir été ajouté dans le dépôt source, modifié (ou pas) ou bien avoir été supprimé. Récupérez et indexez chaque élément nouveau ou modifié. Retirez de l'index ceux qui n'existent plus dans le dépôt source.

La méthode getDoc() accepte un élément de la file d'attente d'indexation Google Cloud Search. Pour chaque élément de la file d'attente, vous accomplirez les tâches suivantes dans la méthode getDoc() :

  1. Vérifiez si l'élément figure dans le dépôt, d'après son ID dans la file d'attente d'indexation Google Cloud Search. Si ce n'est pas le cas, supprimez-le de l'index. Si l'élément existe, passez à l'étape suivante. Si l'élément ne figure pas dans le dépôt, supprimez-le de l'index.

  2. Pour les éléments d'index nouveaux ou modifiés, procédez comme suit :

    1. Définissez les autorisations.
    2. Définissez les métadonnées de l'élément que vous indexez.
    3. Combinez les métadonnées et l'élément dans un objet RepositoryDoc indexable.
    4. Placez les éléments enfants dans la file d'attente d'indexation Google Cloud Search afin qu'ils soient traités.
    5. Renvoyez l'objet RepositoryDoc.

Traiter les éléments supprimés

L'extrait de code suivant indique comment déterminer si un élément figure dans l'index et, s'il ne s'y trouve pas, comment le supprimer.

GraphTraversalSample.java
String resourceName = item.getName();
if (documentExists(resourceName)) {
  return buildDocumentAndChildren(resourceName);
}
// Document doesn't exist, delete it
log.info(() -> String.format("Deleting document %s", resourceName));
return ApiOperations.deleteItem(resourceName);

Définir les autorisations pour un élément

Votre dépôt s'appuie sur une liste de contrôle d'accès (LCA) pour identifier les utilisateurs ou les groupes ayant accès à un élément. Une LCA est une liste d'ID désignant ces groupes ou ces utilisateurs.

Pour que les utilisateurs ayant accès à un élément soient les seuls à pouvoir le voir dans un résultat de recherche, vous devez dupliquer la LCA correspondante dans la source de données. Par conséquent, cette liste doit être incluse lors de l'indexation de l'élément afin que Google Cloud Search dispose des informations nécessaires pour accorder le niveau d'accès qui convient.

Le SDK Content Connector propose un vaste choix de classes et de méthodes pour modéliser les LCA de la plupart des dépôts. Pour chaque élément de votre dépôt, il vous faut analyser la LCA associée et créer une liste correspondante pour Google Cloud Search au moment d'indexer l'élément. Il se peut que la LCA de votre dépôt repose sur des concepts qui compliquent la tâche de modélisation, comme l'héritage de liste. Consultez les informations sur les LCA de Google Cloud Search pour en savoir plus.

Remarque : L'API Cloud Search Indexing accepte les LCA à domaine unique, mais pas les LCA interdomaines. Pour l'essentiel, vous utiliserez la classe Acl.Builder pour définir l'accès à chaque élément via une LCA. L'extrait de code suivant, tiré de l'exemple de balayage complet, permet à tous les utilisateurs ou "comptes principaux" (getCustomerPrincipal()) d'être des "lecteurs" de tous les éléments (.setReaders()) dans le cadre d'une recherche.

FullTraversalSample.java
// Make the document publicly readable within the domain
Acl acl = new Acl.Builder()
    .setReaders(Collections.singletonList(Acl.getCustomerPrincipal()))
    .build();

Vous devez savoir comment fonctionnent les LCA afin de les modéliser correctement pour la source de données. Il se peut que les fichiers à indexer soient stockés dans un système de fichiers basé sur un modèle d'héritage, dans lequel les dossiers enfants héritent des autorisations des dossiers parents. La modélisation du mécanisme d'héritage des LCA nécessite des connaissances supplémentaires. Pour en savoir plus, consultez les informations sur les LCA de Google Cloud Search.

Définir les métadonnées d'un élément

Les métadonnées sont stockées dans un objet Item. La création d'un objet Item nécessite un minimum d'informations : un ID de chaîne unique ainsi que le type, la LCA, l'URL et la version de l'élément. L'extrait de code suivant indique comment créer un objet Item avec la classe auxiliaire IndexingItemBuilder.

GraphTraversalSample.java
// Url is required. Use google.com as a placeholder for this sample.
String viewUrl = "https://www.google.com";

// Version is required, set to current timestamp.
byte[] version = Longs.toByteArray(System.currentTimeMillis());

// Using the SDK item builder class to create the document with
// appropriate attributes. This can be expanded to include metadata
// fields etc.
Item item = IndexingItemBuilder.fromConfiguration(documentId)
    .setItemType(IndexingItemBuilder.ItemType.CONTENT_ITEM)
    .setAcl(acl)
    .setSourceRepositoryUrl(IndexingItemBuilder.FieldOrValue.withValue(viewUrl))
    .setVersion(version)
    .build();

Créer l'élément indexable

Après avoir défini les métadonnées de l'élément, vous pouvez créer l'élément indexable avec la classe RepositoryDoc.Builder. L'exemple suivant vous montre la marche à suivre.

GraphTraversalSample.java
// For this sample, content is just plain text
String content = String.format("Hello world from sample doc %s", documentId);
ByteArrayContent byteContent = ByteArrayContent.fromString("text/plain", content);

RepositoryDoc.Builder docBuilder = new RepositoryDoc.Builder()
    .setItem(item)
    .setContent(byteContent, IndexingService.ContentFormat.TEXT);

Un RepositoryDoc est un type d'objet ApiOperation qui exécute la requête IndexingService.indexItem().

Vous pouvez également vous servir de la méthode setRequestMode() de la classe RepositoryDoc.Builder pour définir le mode de requête d'indexation (ASYNCHRONOUS ou SYNCHRONOUS) :

ASYNCHRONOUS
Le mode asynchrone augmente la latence entre l'indexation et la diffusion des éléments, mais autorise un débit supérieur pour les requêtes d'indexation. Il est recommandé pour l'indexation initiale (le remplissage) du dépôt complet.
SYNCHRONOUS
Le mode synchrone diminue la latence entre l'indexation et la diffusion des éléments, mais autorise un débit moindre. Il est recommandé pour l'indexation des mises à jour et des modifications apportées au dépôt. Si vous n'indiquez pas de mode de requête, la valeur SYNCHRONOUS est attribuée par défaut.

Placer les ID des éléments enfants dans la file d'attente d'indexation Google Cloud Search

L'extrait de code suivant montre comment placer dans la file d'attente les ID des éléments enfants de l'élément parent en cours de traitement. Ces éléments seront traités après que l'élément parent a été indexé.

GraphTraversalSample.java
// Queue the child nodes to visit after indexing this document
Set<String> childIds = getChildItemNames(documentId);
for (String id : childIds) {
  log.info(() -> String.format("Pushing child node %s", id));
  PushItem pushItem = new PushItem();
  docBuilder.addChildId(id, pushItem);
}

RepositoryDoc doc = docBuilder.build();

Étapes suivantes

Voici quelques étapes supplémentaires que vous pouvez effectuer :

Créer un connecteur de contenu à l'aide de l'API REST

Les sections suivantes expliquent comment créer un connecteur de contenu à l'aide de l'API REST.

Déterminer votre stratégie de balayage

La fonction principale d'un connecteur de contenu consiste à balayer un dépôt et à en indexer les données. C'est pourquoi vous devez mettre en place une stratégie de balayage adaptée à la taille des données et à leur disposition dans votre dépôt. Voici trois stratégies de balayage fréquemment employées :

Stratégie de balayage complet

La stratégie de balayage complet consiste à analyser le dépôt entier et à en indexer automatiquement chaque élément. Cette stratégie est couramment employée avec les dépôts de petite taille, lorsque l'entreprise peut se permettre cette opération à chaque indexation.

Cette stratégie de balayage est indiquée pour les dépôts de petite taille, renfermant principalement des données statiques non hiérarchisées. Elle convient également lorsque la détection des modifications est complexe ou incompatible avec le dépôt.

Stratégie de balayage de liste

La stratégie de balayage de liste consiste à analyser le dépôt entier, y compris les nœuds enfants, tout en déterminant l'état de chaque élément. Puis, lors d'une seconde passe, le connecteur n'indexe que les éléments nouveaux ou mis à jour depuis la dernière indexation. Cette stratégie est fréquemment utilisée pour actualiser progressivement un index existant (et éviter ainsi un balayage complet à chaque mise à jour de l'index).

Cette stratégie de balayage convient dans les situations suivantes : la détection des modifications est complexe ou incompatible avec le dépôt, les données ne sont pas hiérarchisées ou vous travaillez avec des ensembles de données très volumineux.

Stratégie de balayage de graphe

La stratégie de balayage de graphe consiste à analyser l'intégralité du nœud parent en déterminant l'état de chaque élément. Puis, lors d'une seconde passe, le connecteur n'indexe que les éléments du nœud racine qui sont nouveaux ou ont été mis à jour depuis la dernière indexation. Il traite enfin les ID des éléments enfants, puis indexe les éléments nouveaux ou mis à jour au niveau de ces nœuds. Il procède ainsi de manière récursive avec chaque nœud enfant jusqu'à ce que tous les éléments aient été traités. Cette stratégie de balayage est généralement retenue avec les dépôts hiérarchiques pour lesquels il est difficile d'établir une liste exhaustive des ID.

Cette stratégie convient pour explorer des données hiérarchisées, comme une série de répertoires ou de pages Web.

Déployer votre stratégie de balayage et vos éléments d'index

Chaque élément indexable destiné à Google Cloud Search est appelé élément dans l'API Cloud Search. Il peut s'agir d'un fichier, d'un dossier, d'une ligne dans un fichier CSV ou d'un enregistrement de base de données.

Une fois le schéma enregistré, vous pouvez remplir l'index en :

  1. appelant items.get pour obtenir un élément (item) à indexer ;
  2. utilisant items.index pour indexer l'élément. Lorsque le schéma utilise la définition d'objet dans le schéma de film, par exemple, une requête d'indexation pour un seul élément se présente comme suit :
{
  "name": "datasource/<data_source_id>/items/titanic",
  "acl": {
    "readers": [
      {
        "gsuitePrincipal": {
          "gsuiteDomain": true
        }
      }
    ]
  },
  "metadata": {
    "title": "Titanic",
    "viewUrl": "http://www.imdb.com/title/tt2234155/?ref_=nv_sr_1",
    "objectType": "movie"
  },
  "structuredData": {
    "object": {
      "properties": [
        {
          "name": "movieTitle",
          "textValues": {
            "values": [
              "Titanic"
            ]
          }
        },
        {
          "name": "releaseDate",
          "dateValues": {
            "values": [
              {
                "year": 1997,
                "month": 12,
                "day": 19
              }
            ]
          }
        },
        {
          "name": "actorName",
          "textValues": {
            "values": [
              "Leonardo DiCaprio",
              "Kate Winslet",
              "Billy Zane"
            ]
          }
        },
        {
          "name": "genre",
          "enumValues": {
            "values": [
              "Drama",
              "Action"
            ]
          }
        },
        {
          "name": "userRating",
          "integerValues": {
            "values": [
              8
            ]
          }
        },
        {
          "name": "mpaaRating",
          "textValues": {
            "values": [
              "PG-13"
            ]
          }
        },
        {
          "name": "duration",
          "textValues": {
            "values": [
              "3 h 14 min"
            ]
          }
        }
      ]
    }
  },
  "content": {
    "inlineContent": "A seventeen-year-old aristocrat falls in love with a kind but poor artist aboard the luxurious, ill-fated R.M.S. Titanic.",
    "contentFormat": "TEXT"
  },
  "version": "01",
  "itemType": "CONTENT_ITEM"
}

Avec une stratégie de balayage complet, vous devez régulièrement réindexer tout le dépôt. Dans le cas d'un balayage de liste ou de graphe, du code doit être ajouté pour pouvoir gérer les modifications du dépôt.

Gérer les modifications du dépôt

Il est possible de rassembler et d'indexer régulièrement les différents éléments d'un dépôt afin de procéder à une indexation complète. Votre index sera certes toujours à jour, mais cette technique peut s'avérer coûteuse avec des dépôts plus grands ou hiérarchisés.

Au lieu de multiplier les appels d'index pour indexer un dépôt entier, vous pouvez vous servir de la file d'attente d'indexation Google Cloud Search. Cette file d'attente permet d'effectuer le suivi des modifications des éléments et d'indexer uniquement ceux qui ont changé. Servez-vous des requêtes items.push pour placer des éléments dans la file d'attente ; vous pourrez interroger et mettre à jour ces éléments plus tard. Consultez l'article File d'attente d'indexation Google Cloud pour en savoir plus.

Pour en savoir plus sur l'API REST de Cloud Search, consultez l'article API Cloud Search.