Crea un connettore di contenuti

Un connettore di contenuti è un programma software utilizzato per attraversare i dati in un repository aziendale e completare un'origine dati. Google offre le seguenti opzioni per lo sviluppo dei connettori di contenuti:

  • L'SDK del connettore di contenuti. Questa è una buona opzione se stai programmando in Java. L'SDK Content Connector è un wrapper attorno all'API REST che consente di creare rapidamente i connettori. Per creare un connettore di contenuti utilizzando l'SDK, consulta la pagina Creare un connettore di contenuti utilizzando l'SDK di Content Connector.

  • API REST o librerie API di basso livello. Usa queste opzioni se non stai programmando in Java o se il tuo codebase supporta meglio un'API REST o una libreria. Per creare un connettore di contenuti utilizzando l'API REST, consulta Creare un connettore di contenuti utilizzando l'API REST.

Un tipico connettore di contenuti esegue le seguenti attività:

  1. Legge ed elabora i parametri di configurazione.
  2. Estrae blocchi discreti di dati indicizzabili, chiamati "items", dal repository di contenuti di terze parti.
  3. Combina ACL, metadati e dati sui contenuti in elementi indicizzabili.
  4. Indicizza gli elementi nell'origine dati di Cloud Search.
  5. (Facoltativo) Ascolta le notifiche delle modifiche dal repository di contenuti di terze parti. Le notifiche di modifica vengono convertite in richieste di indicizzazione per mantenere sincronizzata l'origine dati di Cloud Search con il repository di terze parti. Il connettore esegue questa attività solo se il repository supporta il rilevamento delle modifiche.

Creare un connettore di contenuti utilizzando l'SDK di Content Connector

Le seguenti sezioni spiegano come creare un connettore di contenuti utilizzando l'SDK del connettore di contenuti.

configura le dipendenze

Per utilizzare l'SDK, devi includere determinate dipendenze nel file di build. Fai clic su una scheda in basso per visualizzare le dipendenze per l'ambiente di build:

Maven

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

Gradle

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

Crea la configurazione del connettore

Ogni connettore ha un file di configurazione contenente i parametri utilizzati dal connettore, ad esempio l'ID del repository. I parametri sono definiti come coppie chiave-valore, ad esempio api.sourceId=1234567890abcdef.

L'SDK Google Cloud Search contiene diversi parametri di configurazione forniti da Google utilizzati da tutti i connettori. Devi dichiarare i seguenti parametri forniti da Google nel file di configurazione:

  • Per un connettore di contenuti, devi dichiarare api.sourceId e api.serviceAccountPrivateKeyFile poiché questi parametri identificano la posizione del repository e la chiave privata necessaria per accedere al repository.
  • Per un connettore di identità, devi dichiarare api.identitySourceId poiché questo parametro identifica la località dell'origine identità esterna. Se esegui la sincronizzazione degli utenti, devi anche dichiarare api.customerId come ID univoco dell'account Google Workspace della tua azienda.

A meno che tu non voglia sostituire i valori predefiniti di altri parametri forniti da Google, non è necessario dichiararli nel file di configurazione. Per saperne di più sui parametri di configurazione forniti da Google, ad esempio su come generare determinati ID e chiavi, consulta la sezione Parametri di configurazione forniti da Google.

Puoi anche definire parametri specifici per il repository da utilizzare nel file di configurazione.

Passa il file di configurazione al connettore

Imposta la proprietà di sistema config in modo da passare il file di configurazione al connettore. Puoi impostare la proprietà utilizzando l'argomento -D quando avvii il connettore. Ad esempio, il comando seguente avvia il connettore con il file di configurazione MyConfig.properties:

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

Se questo argomento non è presente, l'SDK tenta di accedere a un file di configurazione predefinito denominato connector-config.properties.

Definisci la tua strategia di attraversamento

La funzione principale di un connettore di contenuti è attraversare un repository e indicizzarne i dati. Devi implementare una strategia di attraversamento in base alle dimensioni e al layout dei dati nel tuo repository. Puoi creare la tua strategia o scegliere tra le seguenti strategie implementate nell'SDK:

Strategia di attraversamento completo

Una strategia di attraversamento completa esegue la scansione dell'intero repository e indicizza in modo invisibile ogni elemento. Questa strategia viene di solito utilizzata quando hai un repository di piccole dimensioni e può permetterti di gestire un attraversamento completo a ogni indicizzazione.

Questa strategia di attraversamento è adatta per repository di piccole dimensioni con dati per lo più statici e non gerarchici. Puoi utilizzare questa strategia di attraversamento anche quando il rilevamento delle modifiche è difficile o non è supportato dal repository.

Strategia di attraversamento elenco

Una strategia di attraversamento elenco analizza l'intero repository, inclusi tutti i nodi figlio, determinando lo stato di ogni elemento. Poi, il connettore esegue un secondo passaggio e indicizza solo gli elementi nuovi o che sono stati aggiornati dall'ultima indicizzazione. Questa strategia di solito viene utilizzata per eseguire aggiornamenti incrementali a un indice esistente (anziché dover eseguire un attraversamento completo ogni volta che aggiorni l'indice).

Questa strategia di attraversamento è adatta quando il rilevamento delle modifiche è difficile o non è supportato dal repository, disponi di dati non gerarchici e lavori con set di dati di grandi dimensioni.

Attraversamento grafico

Una strategia di attraversamento grafico esegue la scansione dell'intero nodo padre determinando lo stato di ogni elemento. Quindi, il connettore esegue un secondo passaggio e indicizza solo gli elementi nel nodo radice sono nuovi o sono stati aggiornati dall'ultima indicizzazione. Infine, il connettore passa tutti gli ID figlio e quindi indicizza gli elementi nuovi o aggiornati nei nodi secondari. Il connettore continua in modo ricorsivo attraverso tutti i nodi secondari fino a quando non vengono corretti tutti gli elementi. Questo attraversamento viene generalmente utilizzato per i repository gerarchici in cui l'elenco di tutti gli ID non è pratico.

Questa strategia è adatta se hai dati gerarchici che devono essere sottoposti a scansione, come una serie di directory o pagine web.

Ognuna di queste strategie di attraversamento viene implementata da una classe di connettore modello nell'SDK. Sebbene tu possa implementare la tua strategia di attraversamento, questi modelli velocizzano notevolmente lo sviluppo del connettore. Per creare un connettore utilizzando un modello, vai alla sezione corrispondente alla tua strategia di attraversamento:

Crea un connettore attraversamento completo utilizzando una classe di modello

Questa sezione della documentazione fa riferimento agli snippet di codice dell'esempio FullTraversalSample.

Implementare il punto di ingresso del connettore

Il punto di ingresso a un connettore è il metodo main(). L'attività principale di questo metodo è creare un'istanza della classe Application e richiamare il relativo metodo start() per eseguire il connettore.

Prima di chiamare application.start(), utilizza la classe IndexingApplication.Builder per creare un'istanza del modello FullTraversalConnector. L'oggetto FullTraversalConnector accetta un oggetto Repository di cui implementi i metodi. Il seguente snippet di codice mostra come implementare il metodo 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();
}

Dietro le quinte, l'SDK chiama il metodo initConfig() dopo le chiamate al metodo main() del connettore Application.build. Il metodo initConfig() esegue le seguenti attività:

  1. Chiama il metodo Configuation.isInitialized() per garantire che Configuration non sia stato inizializzato.
  2. Inizializza un oggetto Configuration con le coppie chiave-valore fornite da Google. Ogni coppia chiave-valore è archiviata in un oggetto ConfigValue all'interno dell'oggetto Configuration.

Implementare l'interfaccia di Repository

L'unico scopo dell'oggetto Repository è eseguire l'attraversamento e l'indicizzazione degli elementi del repository. Quando utilizzi un modello, devi eseguire l'override solo di alcuni metodi all'interno dell'interfaccia Repository per creare un connettore di contenuti. I metodi di cui esegui l'override dipendono dal modello e dalla strategia di attraversamento che utilizzi. Per FullTraversalConnector, sostituisci i seguenti metodi:

  • Il metodo init(). Per eseguire la configurazione e l'inizializzazione del repository di dati, sostituisci il metodo init().

  • Il metodo getAllDocs(). Per attraversare e indicizzare tutti gli elementi nel repository di dati, sostituisci il metodo getAllDocs(). Questo metodo viene chiamato una volta per ogni attraversamento pianificato (come definito dalla tua configurazione).

  • (Facoltativo) Il metodo getChanges(). Se il repository supporta il rilevamento delle modifiche, esegui l'override del metodo getChanges(). Questo metodo viene chiamato una volta per ogni trasferimento incrementale pianificato (come definito dalla tua configurazione) per recuperare gli elementi modificati e indicizzarli.

  • (Facoltativo) Il metodo close(). Se devi eseguire la pulizia del repository, sostituisci il metodo close(). Questo metodo viene chiamato una volta durante l'arresto del connettore.

Ciascuno dei metodi dell'oggetto Repository restituisce un tipo di oggetto ApiOperation. Un oggetto ApiOperation esegue un'azione nella forma di una singola, o forse, più, chiamate IndexingService.indexItem() per eseguire l'indicizzazione effettiva del repository.

Ottieni parametri di configurazione personalizzati

Nell'ambito della gestione della configurazione del connettore, dovrai ottenere parametri personalizzati dall'oggetto Configuration. Questa attività di solito viene eseguita nel metodo init() di una classe Repository.

La classe Configuration offre diversi metodi per ottenere tipi di dati diversi da una configurazione. Ogni metodo restituisce un oggetto ConfigValue. Successivamente, utilizzerai il metodo get() dell'oggetto ConfigValue per recuperare il valore effettivo. Il seguente snippet, da FullTraversalSample, mostra come recuperare un singolo valore intero personalizzato da un oggetto Configuration:

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

Per ottenere e analizzare un parametro contenente diversi valori, utilizza uno dei parser dei tipi della classe Configuration per analizzare i dati in blocchi discreti. Lo snippet seguente del connettore del tutorial utilizza il metodo getMultiValue per ottenere un elenco dei nomi di repository GitHub:

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

Esegui un attraversamento completo

Esegui l'override di getAllDocs() per eseguire un attraversamento completo e l'indicizzazione del repository. Il metodo getAllDocs() accetta un checkpoint. Il checkpoint viene utilizzato per riprendere l'indicizzazione in un elemento specifico in caso di interruzione del processo. Per ogni elemento del tuo repository, esegui questi passaggi nel getAllDocs()metodo:

  1. Impostare le autorizzazioni.
  2. Imposta i metadati per l'elemento che stai indicizzando.
  3. Combina i metadati e l'elemento in un unico elemento RepositoryDoc indicizzabile.
  4. Raggruppa ogni elemento indicizzabile in un iteratore restituito dal metodo getAllDocs(). Tieni presente che getAllDocs() in realtà restituisce un'istanza CheckpointCloseableIterable ovvero un'iterazione di ApiOperation oggetti, ognuno dei quali rappresenta una richiesta API eseguita su RepositoryDoc, ad esempio l'indicizzazione.

Se l'insieme di elementi è troppo grande per essere elaborato in un'unica chiamata, includi un checkpoint e imposta hasMore(true) per indicare che sono disponibili altri elementi per l'indicizzazione.

Impostare le autorizzazioni per un elemento

Il repository utilizza un elenco di controllo dell'accesso (ACL) per identificare gli utenti o i gruppi che hanno accesso a un elemento. Un ACL è un elenco di ID per gruppi o utenti che possono accedere all'elemento.

Devi duplicare l'ACL utilizzato dal tuo repository per garantire che solo gli utenti con accesso a un elemento possano vedere l'elemento in un risultato di ricerca. L'ACL di un elemento deve essere incluso durante l'indicizzazione di un elemento, in modo che Google Cloud Search disponga delle informazioni necessarie per fornire il livello di accesso corretto all'elemento.

L'SDK di Content Connector offre un ricco set di classi e metodi ACL per modellare gli ACL della maggior parte dei repository. Devi analizzare l'ACL per ogni elemento nel repository e creare un ACL corrispondente per Google Cloud Search quando indicizzi un elemento. Se l'ACL del repository utilizza concetti quali l'ereditarietà dell'ACL, la modellazione dell'ACL può essere complicata. Per saperne di più sugli ACL di Google Cloud Search, consulta la pagina relativa agli ACL di Google Cloud Search.

Nota:l'API Cloud Search Index supporta gli ACL a dominio singolo. Non supporta gli ACL interdominio. Utilizza la classe Acl.Builder per impostare l'accesso a ogni elemento utilizzando un ACL. Il seguente snippet di codice, tratto dall'esempio di attraversamento completo, consente a tutti gli utenti o "entità" (getCustomerPrincipal()) di essere "lettori" di tutti gli elementi (.setReaders()) quando eseguono una ricerca.

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

Devi conoscere gli ACL per modellare correttamente gli ACL per il repository. Ad esempio, potresti indicizzare i file all'interno di un file system che utilizza un modello di ereditarietà in cui le cartelle secondarie ereditano le autorizzazioni dalle cartelle principali. L'ereditarietà della modellazione dell'ACL richiede informazioni aggiuntive coperte negli ACL di Google Cloud Search

Impostare i metadati per un elemento

I metadati sono archiviati in un oggetto Item. Per creare un Item, sono necessari almeno un ID stringa, un tipo di elemento, un ACL, un URL e una versione univoci dell'elemento. Il seguente snippet di codice mostra come creare un Item utilizzando la classe helper 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();

Crea l'elemento indicizzabile

Dopo aver impostato i metadati dell'elemento, puoi creare l'effettivo elemento indicizzabile utilizzando la classe RepositoryDoc.Builder. L'esempio seguente mostra come creare un singolo elemento indicizzabile.

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 è un tipo di ApiOperation che esegue l'effettiva richiesta IndexingService.indexItem().

Puoi anche utilizzare il metodo setRequestMode() della classe RepositoryDoc.Builder per identificare la richiesta di indicizzazione come ASYNCHRONOUS o SYNCHRONOUS:

ASYNCHRONOUS
La modalità asincrona genera una latenza dall'indicizzazione alla pubblicazione più lunga e soddisfa una quota di velocità effettiva elevata per le richieste di indicizzazione. La modalità asincrona è consigliata per l'indicizzazione iniziale (backfill) dell'intero repository.
SYNCHRONOUS
La modalità sincrona riduce la latenza dall'indicizzazione alla pubblicazione e soddisfa una quota di velocità effettiva limitata. La modalità sincrona è consigliata per l'indicizzazione di aggiornamenti e modifiche al repository. Se non viene specificato, il valore predefinito della modalità di richiesta è SYNCHRONOUS.

Raggruppa ogni elemento indicizzabile in un iteratore

Il metodo getAllDocs() restituisce un valore Iterator, in particolare CheckpointCloseableIterable, di oggetti RepositoryDoc. Puoi utilizzare la classe CheckpointClosableIterableImpl.Builder per creare e restituire un iteratore. Il seguente snippet di codice mostra come creare e restituire un iteratore.

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

L'SDK esegue ogni chiamata di indicizzazione racchiusa all'interno dell'iteratore.

Passaggi successivi

Ecco alcune operazioni che puoi eseguire:

Crea un connettore di attraversamento elenco utilizzando una classe di modello

La coda di indicizzazione di Cloud Search viene utilizzata per contenere ID e valori hash facoltativi per ogni elemento nel repository. Un connettore attraversamento elenco invia gli ID elemento alla coda di indicizzazione di Google Cloud Search e li recupera uno alla volta per l'indicizzazione. Google Cloud Search gestisce le code e confronta i contenuti delle code per determinare lo stato degli elementi, ad esempio se un elemento è stato eliminato dal repository. Per saperne di più sulla coda di indicizzazione di Cloud Search, consulta La coda di indicizzazione di Cloud Search.

Questa sezione della documentazione fa riferimento agli snippet di codice dell'esempio ListTraversalSample.

Implementare il punto di ingresso del connettore

Il punto di ingresso a un connettore è il metodo main(). L'attività principale di questo metodo è creare un'istanza della classe Application e richiamare il relativo metodo start() per eseguire il connettore.

Prima di chiamare application.start(), utilizza la classe IndexingApplication.Builder per creare un'istanza del modello ListingConnector. ListingConnector accetta un oggetto Repository di cui implementi i metodi. Il seguente snippet mostra come instaurare un ListingConnector e il relativo Repository:

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();
}

Dietro le quinte, l'SDK chiama il metodo initConfig() dopo le chiamate al metodo main() del connettore Application.build. Il metodo initConfig():

  1. Chiama il metodo Configuation.isInitialized() per garantire che Configuration non sia stato inizializzato.
  2. Inizializza un oggetto Configuration con le coppie chiave-valore fornite da Google. Ogni coppia chiave-valore è archiviata in un oggetto ConfigValue all'interno dell'oggetto Configuration.

Implementare l'interfaccia di Repository

L'unico scopo dell'oggetto Repository è eseguire l'attraversamento e l'indicizzazione degli elementi del repository. Quando utilizzi un modello, per creare un connettore di contenuti devi solo eseguire l'override di determinati metodi nell'interfaccia di Repository. I metodi di cui esegui l'override dipendono dal modello e dalla strategia di attraversamento che utilizzi. Per ListingConnector, sostituisci i seguenti metodi:

  • Il metodo init(). Per eseguire la configurazione e l'inizializzazione del repository di dati, sostituisci il metodo init().

  • Il metodo getIds(). Per recuperare gli ID e i valori hash per tutti i record nel repository, esegui l'override del metodo getIds().

  • Il metodo getDoc(). Per aggiungere nuovi elementi, aggiornare, modificare o eliminare elementi dall'indice, sostituisci il metodo getDoc().

  • (Facoltativo) Il metodo getChanges(). Se il repository supporta il rilevamento delle modifiche, esegui l'override del metodo getChanges(). Questo metodo viene chiamato una volta per ogni trasferimento incrementale pianificato (come definito dalla tua configurazione) per recuperare gli elementi modificati e indicizzarli.

  • (Facoltativo) Il metodo close(). Se devi eseguire la pulizia del repository, sostituisci il metodo close(). Questo metodo viene chiamato una volta durante l'arresto del connettore.

Ciascuno dei metodi dell'oggetto Repository restituisce un tipo di oggetto ApiOperation. Un oggetto ApiOperation esegue un'azione nella forma di una singola, o forse, più, chiamate IndexingService.indexItem() per eseguire l'indicizzazione effettiva del repository.

Ottieni parametri di configurazione personalizzati

Nell'ambito della gestione della configurazione del connettore, dovrai ottenere parametri personalizzati dall'oggetto Configuration. Questa attività di solito viene eseguita nel metodo init() di una classe Repository.

La classe Configuration offre diversi metodi per ottenere tipi di dati diversi da una configurazione. Ogni metodo restituisce un oggetto ConfigValue. Successivamente, utilizzerai il metodo get() dell'oggetto ConfigValue per recuperare il valore effettivo. Il seguente snippet, da FullTraversalSample, mostra come recuperare un singolo valore intero personalizzato da un oggetto Configuration:

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

Per ottenere e analizzare un parametro contenente diversi valori, utilizza uno dei parser dei tipi della classe Configuration per analizzare i dati in blocchi discreti. Lo snippet seguente del connettore del tutorial utilizza il metodo getMultiValue per ottenere un elenco dei nomi di repository GitHub:

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

Esegui il attraversamento elenco

Esegui l'override del metodo getIds() per recuperare ID e valori hash per tutti i record nel repository. Il metodo getIds() accetta un checkpoint. Il checkpoint viene utilizzato per riprendere l'indicizzazione su un elemento specifico in caso di interruzione del processo.

A questo punto, esegui l'override del metodo getDoc() per gestire ogni elemento nella coda di indicizzazione di Cloud Search.

Esegui il push di ID elemento e valori hash

Esegui l'override di getIds() per recuperare gli ID elemento e i valori hash dei contenuti associati dal repository. Le coppie di ID e valori hash vengono quindi pacchettizzate in una richiesta di operazione push alla coda di indicizzazione di Cloud Search. In genere, gli ID radice o padre vengono inviati per primi, seguiti dagli ID figlio fino a quando l'intera gerarchia di elementi non viene elaborata.

Il metodo getIds() accetta un checkpoint che rappresenta l'ultimo elemento da indicizzare. Il checkpoint può essere utilizzato per riprendere l'indicizzazione in un elemento specifico in caso di interruzione del processo. Per ogni elemento del repository, esegui questi passaggi nel metodo getIds():

  • Recupera ogni ID elemento e valore hash associato dal repository.
  • Raggruppa ogni coppia di ID e valore hash in una PushItems.
  • Combina ogni PushItems in un iteratore restituito dal metodo getIds(). Tieni presente che getIds() in realtà restituisce un'istanza CheckpointCloseableIterable ovvero un'iterazione di ApiOperation oggetti, ogni oggetto che rappresenta una richiesta API eseguita su un RepositoryDoc , ad esempio il push degli elementi alla coda.

Il seguente snippet di codice mostra come ottenere ogni ID articolo e valore hash e inserirli in un PushItems. Una PushItems è una richiesta ApiOperation per eseguire il push di un elemento alla coda di indicizzazione di 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);
}

Il seguente snippet di codice mostra come utilizzare la classe PushItems.Builder per pacchettizzare gli ID e i valori hash in un unico push ApiOperation.

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

Gli elementi vengono inviati alla coda di indicizzazione di Cloud Search per un'ulteriore elaborazione.

Recupera e gestisci ogni elemento

Esegui l'override di getDoc() per gestire ogni elemento nella coda di indicizzazione di Cloud Search. Un elemento può essere nuovo, modificato, modificato o non più esistente nel repository di origine. Recupera e indicizza ogni elemento nuovo o modificato. Rimuovi dall'indice gli elementi che non esistono più nel repository di origine.

Il metodo getDoc() accetta un elemento della coda di indicizzazione di Google Cloud Search. Per ogni elemento nella coda, esegui questi passaggi nel metodo getDoc():

  1. Verifica se nel repository esiste l'ID dell'elemento all'interno della coda di indicizzazione di Cloud Search. In caso contrario, elimina l'elemento dall'indice.

  2. Esegui un sondaggio sull'indice per conoscere lo stato dell'elemento e, se un elemento non è stato modificato (ACCEPTED), non fare nulla.

  3. Indice modificato o elementi nuovi:

    1. Imposta le autorizzazioni.
    2. Imposta i metadati per l'elemento che stai indicizzando.
    3. Combina i metadati e l'elemento in un unico elemento RepositoryDoc indicizzabile.
    4. Restituisci RepositoryDoc.

Nota: il modello ListingConnector non supporta la restituzione di null nel metodo getDoc(). La restituzione di null restituisce un NullPointerException.

Gestire gli elementi eliminati

Il seguente snippet di codice mostra come determinare se un elemento esiste nel repository ed eventualmente eliminarlo.

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);
}

Tieni presente che documents è una struttura di dati che rappresenta il repository. Se documentID non si trova in documents, restituisce APIOperations.deleteItem(resourceName) per eliminare l'elemento dall'indice.

Gestire gli elementi non modificati

Il seguente snippet di codice mostra come eseguire il polling dello stato degli elementi nella coda di indicizzazione di Cloud Search e gestire un elemento non modificato.

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();
}

Per determinare se l'elemento non è stato modificato, controlla lo stato dell'elemento e altri metadati che potrebbero indicare una modifica. Nell'esempio, l'hash dei metadati viene utilizzato per determinare se l'elemento è stato modificato.

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);
}

Impostare le autorizzazioni per un elemento

Il repository utilizza un elenco di controllo dell'accesso (ACL) per identificare gli utenti o i gruppi che hanno accesso a un elemento. Un ACL è un elenco di ID per gruppi o utenti che possono accedere all'elemento.

Devi duplicare l'ACL utilizzato dal tuo repository per garantire che solo gli utenti con accesso a un elemento possano vedere l'elemento in un risultato di ricerca. L'ACL di un elemento deve essere incluso durante l'indicizzazione di un elemento, in modo che Google Cloud Search disponga delle informazioni necessarie per fornire il livello di accesso corretto all'elemento.

L'SDK di Content Connector offre un ricco set di classi e metodi ACL per modellare gli ACL della maggior parte dei repository. Devi analizzare l'ACL per ogni elemento nel repository e creare un ACL corrispondente per Google Cloud Search quando indicizzi un elemento. Se l'ACL del repository utilizza concetti quali l'ereditarietà dell'ACL, la modellazione dell'ACL può essere complicata. Per saperne di più sugli ACL di Google Cloud Search, consulta la pagina relativa agli ACL di Google Cloud Search.

Nota:l'API Cloud Search Index supporta gli ACL a dominio singolo. Non supporta gli ACL interdominio. Utilizza la classe Acl.Builder per impostare l'accesso a ogni elemento utilizzando un ACL. Il seguente snippet di codice, tratto dall'esempio di attraversamento completo, consente a tutti gli utenti o "entità" (getCustomerPrincipal()) di essere "lettori" di tutti gli elementi (.setReaders()) quando eseguono una ricerca.

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

Devi conoscere gli ACL per modellare correttamente gli ACL per il repository. Ad esempio, potresti indicizzare i file all'interno di un file system che utilizza un modello di ereditarietà in cui le cartelle secondarie ereditano le autorizzazioni dalle cartelle principali. L'ereditarietà della modellazione dell'ACL richiede informazioni aggiuntive coperte negli ACL di Google Cloud Search

Impostare i metadati per un elemento

I metadati sono archiviati in un oggetto Item. Per creare un Item, sono necessari almeno un ID stringa, un tipo di elemento, un ACL, un URL e una versione univoci dell'elemento. Il seguente snippet di codice mostra come creare un Item utilizzando la classe helper 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();

Crea un elemento indicizzabile

Dopo aver impostato i metadati dell'elemento, puoi creare l'effettivo elemento indicizzabile utilizzando RepositoryDoc.Builder. L'esempio seguente mostra come creare un singolo elemento indicizzabile.

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 è un tipo di ApiOperation che esegue la richiesta IndexingService.indexItem() effettiva.

Puoi anche utilizzare il metodo setRequestMode() della classe RepositoryDoc.Builder per identificare la richiesta di indicizzazione come ASYNCHRONOUS o SYNCHRONOUS:

ASYNCHRONOUS
La modalità asincrona genera una latenza dall'indicizzazione alla pubblicazione più lunga e soddisfa una quota di velocità effettiva elevata per le richieste di indicizzazione. La modalità asincrona è consigliata per l'indicizzazione iniziale (backfill) dell'intero repository.
SYNCHRONOUS
La modalità sincrona riduce la latenza dall'indicizzazione alla pubblicazione e soddisfa una quota di velocità effettiva limitata. La modalità sincrona è consigliata per l'indicizzazione di aggiornamenti e modifiche al repository. Se non viene specificato, il valore predefinito della modalità di richiesta è SYNCHRONOUS.

Passaggi successivi

Ecco alcune operazioni che puoi eseguire:

  • (Facoltativo) Implementa il metodo close() per rilasciare eventuali risorse prima dell'arresto.
  • (Facoltativo) Crea un connettore di identità utilizzando l'SDK del connettore di contenuti.

Crea un connettore di attraversamento grafico utilizzando una classe di modello

La coda di indicizzazione di Cloud Search viene utilizzata per contenere ID e valori hash facoltativi per ogni elemento nel repository. Un connettore di attraversamento grafico invia gli ID elemento alla coda di indicizzazione di Google Cloud Search e li recupera uno alla volta per l'indicizzazione. Google Cloud Search gestisce le code e confronta i contenuti delle code per determinare lo stato degli elementi, ad esempio se un elemento è stato eliminato dal repository. Per saperne di più sulla coda di indicizzazione di Cloud Search, consulta La coda di indicizzazione di Google Cloud Search.

Durante l'indice, i contenuti degli elementi vengono recuperati dal repository dei dati e gli eventuali ID elemento secondari vengono inviati alla coda. Il connettore procede con l'elaborazione ricorsiva degli ID principale e secondario finché non vengono gestiti tutti gli elementi.

Questa sezione della documentazione fa riferimento agli snippet di codice dell'esempio GraphTraversalSample.

Implementare il punto di ingresso del connettore

Il punto di ingresso a un connettore è il metodo main(). L'attività principale di questo metodo è creare un'istanza della classe Application e richiamare il relativo metodo start() per eseguire il connettore.

Prima di chiamare application.start(), utilizza la classe IndexingApplication.Builder per creare un'istanza del modello ListingConnector. L'oggetto ListingConnector accetta un oggetto Repository di cui implementi i metodi.

Il seguente snippet mostra come instaurare un ListingConnector e il relativo Repository:

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();
}

Dietro le quinte, l'SDK chiama il metodo initConfig() dopo le chiamate al metodo main() del connettore Application.build. Il metodo initConfig():

  1. Chiama il metodo Configuation.isInitialized() per garantire che Configuration non sia stato inizializzato.
  2. Inizializza un oggetto Configuration con le coppie chiave-valore fornite da Google. Ogni coppia chiave-valore è archiviata in un oggetto ConfigValue all'interno dell'oggetto Configuration.

Implementare l'interfaccia di Repository

L'unico scopo dell'oggetto Repository è eseguire il attraversamento e l'indicizzazione degli elementi del repository. Quando utilizzi un modello, devi eseguire l'override solo di alcuni metodi nell'interfaccia di Repository per creare un connettore di contenuti. I metodi che esegui l'override dipendono dal modello e dalla strategia di attraversamento che utilizzi. Per ListingConnector, esegui l'override dei seguenti metodi:

  • Il metodo init(). Per eseguire la configurazione e l'inizializzazione del repository di dati, sostituisci il metodo init().

  • Il metodo getIds(). Per recuperare gli ID e i valori hash per tutti i record nel repository, esegui l'override del metodo getIds().

  • Il metodo getDoc(). Per aggiungere nuovi elementi, aggiornare, modificare o eliminare elementi dall'indice, sostituisci il metodo getDoc().

  • (Facoltativo) Il metodo getChanges(). Se il repository supporta il rilevamento delle modifiche, esegui l'override del metodo getChanges(). Questo metodo viene chiamato una volta per ogni trasferimento incrementale pianificato (come definito dalla tua configurazione) per recuperare gli elementi modificati e indicizzarli.

  • (Facoltativo) Il metodo close(). Se devi eseguire la pulizia del repository, sostituisci il metodo close(). Questo metodo viene chiamato una volta durante l'arresto del connettore.

Ciascuno dei metodi dell'oggetto Repository restituisce un qualche tipo di oggetto ApiOperation. Un oggetto ApiOperation esegue un'azione nella forma di una singola o più chiamate IndexingService.indexItem() per eseguire l'indicizzazione effettiva del repository.

Ottieni parametri di configurazione personalizzati

Nell'ambito della gestione della configurazione del connettore, dovrai ottenere parametri personalizzati dall'oggetto Configuration. Questa attività di solito viene eseguita nel metodo init() di una classe Repository.

La classe Configuration offre diversi metodi per ottenere tipi di dati diversi da una configurazione. Ogni metodo restituisce un oggetto ConfigValue. Successivamente, utilizzerai il metodo get() dell'oggetto ConfigValue per recuperare il valore effettivo. Il seguente snippet, da FullTraversalSample, mostra come recuperare un singolo valore intero personalizzato da un oggetto Configuration:

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

Per ottenere e analizzare un parametro contenente diversi valori, utilizza uno dei parser dei tipi della classe Configuration per analizzare i dati in blocchi discreti. Lo snippet seguente del connettore del tutorial utilizza il metodo getMultiValue per ottenere un elenco dei nomi di repository GitHub:

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

Eseguire l'attraversamento del grafico

Esegui l'override del metodo getIds() per recuperare ID e valori hash per tutti i record nel repository. Il metodo getIds() accetta un checkpoint. Il checkpoint viene utilizzato per riprendere l'indicizzazione su un elemento specifico in caso di interruzione del processo.

A questo punto, esegui l'override del metodo getDoc() per gestire ogni elemento nella coda di indicizzazione di Cloud Search.

Esegui il push di ID elemento e valori hash

Esegui l'override di getIds() per recuperare gli ID elemento e i valori hash dei contenuti associati dal repository. Le coppie di ID e valori hash vengono quindi pacchettizzate in una richiesta di operazione push alla coda di indicizzazione di Cloud Search. In genere, gli ID radice o padre vengono inviati per primi, seguiti dagli ID figlio fino a quando l'intera gerarchia di elementi non viene elaborata.

Il metodo getIds() accetta un checkpoint che rappresenta l'ultimo elemento da indicizzare. Il checkpoint può essere utilizzato per riprendere l'indicizzazione in un elemento specifico in caso di interruzione del processo. Per ogni elemento del repository, esegui questi passaggi nel metodo getIds():

  • Recupera ogni ID elemento e valore hash associato dal repository.
  • Raggruppa ogni coppia di ID e valore hash in una PushItems.
  • Combina ogni PushItems in un iteratore restituito dal metodo getIds(). Tieni presente che getIds() in realtà restituisce un'istanza CheckpointCloseableIterable ovvero un'iterazione di ApiOperation oggetti, ogni oggetto che rappresenta una richiesta API eseguita su un RepositoryDoc , ad esempio il push degli elementi alla coda.

Il seguente snippet di codice mostra come ottenere ogni ID elemento e valore hash e come inserirli in un PushItems. Una PushItems è una richiesta ApiOperation per eseguire il push di un elemento alla coda di indicizzazione di Cloud Search.

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

Il seguente snippet di codice mostra come utilizzare la classe PushItems.Builder per pacchettizzare gli ID e i valori hash in un unico push ApiOperation.

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

Gli elementi vengono inviati alla coda di indicizzazione di Cloud Search per un'ulteriore elaborazione.

Recupera e gestisci ogni elemento

Esegui l'override di getDoc() per gestire ogni elemento nella coda di indicizzazione di Cloud Search. Un elemento può essere nuovo, modificato, modificato o non più esistente nel repository di origine. Recupera e indicizza ogni elemento nuovo o modificato. Rimuovi dall'indice gli elementi che non esistono più nel repository di origine.

Il metodo getDoc() accetta un elemento della coda di indicizzazione di Cloud Search. Per ogni elemento nella coda, esegui questi passaggi nel metodo getDoc():

  1. Controlla se nel repository esiste l'ID dell'elemento all'interno della coda di indicizzazione di Cloud Search. In caso contrario, elimina l'elemento dall'indice. Se l'elemento esiste, continua con il passaggio successivo.

  2. Indice modificato o elementi nuovi:

    1. Imposta le autorizzazioni.
    2. Imposta i metadati per l'elemento che stai indicizzando.
    3. Combina i metadati e l'elemento in un unico elemento RepositoryDoc indicizzabile.
    4. Inserisci gli ID figlio nella coda di indicizzazione di Cloud Search per un'ulteriore elaborazione.
    5. Restituisci RepositoryDoc.

Gestire gli elementi eliminati

Il seguente snippet di codice mostra come determinare se un elemento esiste nell'indice e come eliminarlo.

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);

Impostare le autorizzazioni per un elemento

Il repository utilizza un elenco di controllo dell'accesso (ACL) per identificare gli utenti o i gruppi che hanno accesso a un elemento. Un ACL è un elenco di ID per gruppi o utenti che possono accedere all'elemento.

Devi duplicare l'ACL utilizzato dal tuo repository per garantire che solo gli utenti con accesso a un elemento possano vedere l'elemento in un risultato di ricerca. L'ACL di un elemento deve essere incluso durante l'indicizzazione di un elemento, in modo che Google Cloud Search disponga delle informazioni necessarie per fornire il livello di accesso corretto all'elemento.

L'SDK di Content Connector offre un ricco set di classi e metodi ACL per modellare gli ACL della maggior parte dei repository. Devi analizzare l'ACL per ogni elemento nel repository e creare un ACL corrispondente per Google Cloud Search quando indicizzi un elemento. Se l'ACL del repository utilizza concetti quali l'ereditarietà dell'ACL, la modellazione dell'ACL può essere complicata. Per saperne di più sugli ACL di Google Cloud Search, consulta la pagina relativa agli ACL di Google Cloud Search.

Nota:l'API Cloud Search Index supporta gli ACL a dominio singolo. Non supporta gli ACL interdominio. Utilizza la classe Acl.Builder per impostare l'accesso a ogni elemento utilizzando un ACL. Il seguente snippet di codice, tratto dall'esempio di attraversamento completo, consente a tutti gli utenti o "entità" (getCustomerPrincipal()) di essere "lettori" di tutti gli elementi (.setReaders()) quando eseguono una ricerca.

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

Devi conoscere gli ACL per modellare correttamente gli ACL per il repository. Ad esempio, potresti indicizzare i file all'interno di un file system che utilizza un modello di ereditarietà in cui le cartelle secondarie ereditano le autorizzazioni dalle cartelle principali. L'ereditarietà della modellazione dell'ACL richiede informazioni aggiuntive coperte negli ACL di Google Cloud Search

Impostare i metadati per un elemento

I metadati sono archiviati in un oggetto Item. Per creare un Item, sono necessari almeno un ID stringa, un tipo di elemento, un ACL, un URL e una versione univoci dell'elemento. Il seguente snippet di codice mostra come creare un Item utilizzando la classe helper 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();

Crea l'elemento indicizzabile

Dopo aver impostato i metadati dell'elemento, puoi creare l'effettivo elemento indicizzabile utilizzando RepositoryDoc.Builder. L'esempio seguente mostra come creare un singolo elemento indicizzabile.

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 è un tipo di ApiOperation che esegue l'effettiva richiesta IndexingService.indexItem().

Puoi anche utilizzare il metodo setRequestMode() della classe RepositoryDoc.Builder per identificare la richiesta di indicizzazione come ASYNCHRONOUS o SYNCHRONOUS:

ASYNCHRONOUS
La modalità asincrona genera una latenza dall'indicizzazione alla pubblicazione più lunga e soddisfa una quota di velocità effettiva elevata per le richieste di indicizzazione. La modalità asincrona è consigliata per l'indicizzazione iniziale (backfill) dell'intero repository.
SYNCHRONOUS
La modalità sincrona riduce la latenza dall'indicizzazione alla pubblicazione e soddisfa una quota di velocità effettiva limitata. La modalità sincrona è consigliata per l'indicizzazione di aggiornamenti e modifiche al repository. Se non viene specificato, il valore predefinito della modalità di richiesta è SYNCHRONOUS.

Inserisci gli ID secondari nella coda di indicizzazione di Cloud Search

Il seguente snippet di codice mostra come includere nella coda per l'elaborazione gli ID figlio per l'elemento principale in fase di elaborazione. Questi ID vengono elaborati dopo l'indicizzazione dell'elemento principale.

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();

Passaggi successivi

Ecco alcune operazioni che puoi eseguire:

Creare un connettore di contenuti utilizzando l'API REST

Le seguenti sezioni spiegano come creare un connettore di contenuti utilizzando l'API REST.

Definisci la tua strategia di attraversamento

La funzione principale di un connettore di contenuti è attraversare un repository e indicizzarne i dati. Devi implementare una strategia di attraversamento in base alle dimensioni e al layout dei dati nel tuo repository. Di seguito sono riportate tre strategie di attraversamento comuni:

Strategia di attraversamento completo

Una strategia di attraversamento completa esegue la scansione dell'intero repository e indicizza in modo invisibile ogni elemento. Questa strategia viene di solito utilizzata quando hai un repository di piccole dimensioni e può permetterti di gestire un attraversamento completo a ogni indicizzazione.

Questa strategia di attraversamento è adatta per repository di piccole dimensioni con dati per lo più statici e non gerarchici. Puoi utilizzare questa strategia di attraversamento anche quando il rilevamento delle modifiche è difficile o non è supportato dal repository.

Strategia di attraversamento elenco

Una strategia di attraversamento elenco analizza l'intero repository, inclusi tutti i nodi figlio, determinando lo stato di ogni elemento. Poi, il connettore esegue un secondo passaggio e indicizza solo gli elementi nuovi o che sono stati aggiornati dall'ultima indicizzazione. Questa strategia di solito viene utilizzata per eseguire aggiornamenti incrementali a un indice esistente (anziché dover eseguire un attraversamento completo ogni volta che aggiorni l'indice).

Questa strategia di attraversamento è adatta quando il rilevamento delle modifiche è difficile o non è supportato dal repository, disponi di dati non gerarchici e lavori con set di dati di grandi dimensioni.

Attraversamento grafico

Una strategia di attraversamento grafico esegue la scansione dell'intero nodo padre determinando lo stato di ogni elemento. Quindi, il connettore esegue un secondo passaggio e indicizza solo gli elementi nel nodo radice sono nuovi o sono stati aggiornati dall'ultima indicizzazione. Infine, il connettore passa tutti gli ID figlio e quindi indicizza gli elementi nuovi o aggiornati nei nodi secondari. Il connettore continua in modo ricorsivo attraverso tutti i nodi secondari fino a quando non vengono corretti tutti gli elementi. Questo attraversamento viene generalmente utilizzato per i repository gerarchici in cui l'elenco di tutti gli ID non è pratico.

Questa strategia è adatta se hai dati gerarchici da sottoporre a scansione, ad esempio le directory di una serie o le pagine web.

Implementa la strategia di attraversamento e l'indicizzazione degli elementi

Ogni elemento indicizzabile per Cloud Search è definito elemento nell'API Cloud Search. Un elemento può essere un file, una cartella, una riga di un file CSV o un record di database.

Una volta registrato lo schema, puoi completare l'indice:

  1. (Facoltativo) Utilizzare items.upload per caricare file di dimensioni superiori a 100 KiB per l'indicizzazione. Per i file più piccoli, incorpora i contenuti come inlineContent utilizzando items.index.

  2. (Facoltativo) Utilizzando media.upload per caricare i file multimediali per l'indicizzazione.

  3. Utilizzare items.index per indicizzare l'elemento. Ad esempio, se lo schema utilizza la definizione dell'oggetto nello schema film, una richiesta di indicizzazione per un singolo elemento sarebbe simile a questa:

    {
      "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"
    }
    
  4. (Facoltativo) Utilizzare le chiamate items.get per verificare che un item sia stato indicizzato.

Per eseguire un attraversamento completo, devi reindicizzare periodicamente l'intero repository. Per eseguire un attraversamento elenco o grafico, devi implementare il codice per gestire le modifiche al repository.

Gestire le modifiche al repository

Puoi raccogliere e indicizzare periodicamente ogni elemento di un repository per eseguire un'indicizzazione completa. Sebbene sia efficace nel garantire che l'indice sia aggiornato, un'indicizzazione completa può essere costosa quando si hanno a che fare con repository gerarchici o di grandi dimensioni.

Anziché utilizzare le chiamate di indicizzazione per indicizzare di tanto in tanto un intero repository, puoi anche utilizzare la coda di indicizzazione di Google Cloud come meccanismo per monitorare le modifiche e indicizzare solo gli elementi che sono cambiati. Puoi utilizzare le richieste items.push per inviare elementi alla coda per eseguire il polling e l'aggiornamento in un secondo momento. Per saperne di più sulla coda di indicizzazione di Google Cloud, consulta Coda di indicizzazione di Google Cloud.

Per saperne di più sull'API Google Cloud Search, consulta la pagina dedicata all'API Cloud Search.