Crea un conector de contenido

Un conector de contenido es un programa de software que desvía los datos en un repositorio empresarial y propaga una fuente de datos. Google brinda las siguientes opciones para desarrollar conectores de contenido:

  • El SDK de Content Connector Esta es una buena opción para los programadores de Java. El SDK es un wrapper alrededor de la API de REST que te permite crear conectores rápidamente. Para crear un conector de contenido con el SDK, consulta Crea un conector de contenido con el SDK de Content Connector.

  • Una API de REST de bajo nivel o bibliotecas de API. Usa estas opciones si no usas Java o si tu base de código se adapta mejor a una API de REST o a una biblioteca. Para crear un conector de contenido con la API de REST, consulta Crea un conector de contenido con la API de REST.

Un conector de contenido típico realiza las siguientes tareas:

  1. Lee y procesa parámetros de configuración.
  2. Extrae fragmentos discretos de datos indexables, llamados "elementos", del repositorio de terceros.
  3. Combina LCA, metadatos y datos de contenido en elementos indexables.
  4. Indexa elementos a la fuente de datos de Cloud Search.
  5. (Opcional) Presta atención a las notificaciones de cambios del repositorio. Las notificaciones de cambios se convierten en solicitudes de indexación para mantener sincronizada la fuente de datos de Cloud Search. El conector solo realiza esta tarea si el repositorio admite la detección de cambios.

Crea un conector de contenido con el SDK de conector de contenido

En las siguientes secciones, se explica cómo crear un conector de contenido con el SDK de Content Connector.

Configura dependencias

Incluye estas dependencias en tu archivo de compilación.

Maven

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

Gradle

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

Crea tu configuración del conector

Cada conector usa un archivo de configuración para parámetros como el ID de tu repositorio. Define los parámetros como pares clave-valor, como api.sourceId=1234567890abcdef.

El SDK de Google Cloud Search incluye parámetros proporcionados por Google para todos los conectores. Debes declarar lo siguiente en tu archivo de configuración:

  • Conector de contenido: Declara api.sourceId y api.serviceAccountPrivateKeyFile. Estos identifican tu repositorio y la clave privada necesaria para acceder a él.
  • Conector de identidad: Declara api.identitySourceId para identificar tu fuente de identidad externa. Para la sincronización de usuarios, también debes declarar api.customerId (el ID único de tu cuenta de Google Workspace).

Declara otros parámetros proporcionados por Google solo para anular sus valores predeterminados. Para obtener detalles sobre cómo generar IDs y claves, consulta Parámetros proporcionados por Google.

También puedes definir parámetros específicos del repositorio en tu archivo de configuración.

Pasa el archivo de configuración al conector

Establece la propiedad del sistema config para pasar el archivo de configuración. Usa el argumento -D cuando inicies el conector. Por ejemplo:

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

Si omites este argumento, el SDK intentará usar un archivo llamado connector-config.properties en el directorio local.

Determina tu estrategia de recorrido

La función primaria de un conector de contenido es recorrer un repositorio y luego indexar sus datos. Debes implementar una estrategia basada en el tamaño y el diseño de tu repositorio. Puedes diseñar tu propia estrategia o elegir una del SDK:

Estrategia de recorrido completo
Analiza todo el repositorio y, luego, indexa cada elemento. Esta estrategia es la mejor para los repositorios pequeños en los que puedes permitirte la sobrecarga de un recorrido completo durante cada indexación. Úsala para repositorios pequeños con datos que son, en su mayoría, estáticos y no jerárquicos, o cuando la detección de cambios es difícil.
Estrategia de recorrido de lista
Analiza todo el repositorio para determinar el estado de cada elemento y, luego, indexa solo los elementos nuevos o actualizados. Úsala para actualizaciones incrementales de un índice grande y no jerárquico cuando no se admita la detección de cambios.
Recorrido de gráficos
Analiza un nodo principal para determinar el estado de sus elementos y, luego, indexa los elementos nuevos o actualizados en ese nodo. Luego, procesa de forma recursiva los nodos secundarios. Usa este método para los repositorios jerárquicos en los que no es práctico hacer una lista de todos los IDs, como las estructuras de directorios o los sitios web.

El SDK implementa estas estrategias en clases de conectores de plantilla. Estas plantillas pueden acelerar tu desarrollo. Para usar una plantilla, consulta la sección correspondiente:

Crea un conector de recorrido completo mediante el uso de una clase de plantilla

En esta sección, se hace referencia al código de FullTraversalSample.

Implementa el punto de entrada del conector

El punto de entrada es el método main(). Crea una instancia de Application y llama a start() para ejecutar el conector.

Antes de llamar a application.start(), usa la clase IndexingApplication.Builder para crear una instancia de la plantilla FullTraversalConnector. Esta plantilla acepta un objeto Repository.

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

El SDK llama a initConfig() después de que tu método main() llama a Application.build(). El método initConfig():

  1. Garantiza que Configuration aún no se haya inicializado.
  2. Inicializa el objeto Configuration con los pares clave-valor proporcionados por Google.

Implementa la interfaz Repository

El objeto Repository recorre e indexa los elementos del repositorio. Cuando usas una plantilla, solo debes anular ciertos métodos en la interfaz Repository. Para FullTraversalConnector, anula lo siguiente:

  • init(): Para la configuración y la inicialización del repositorio.
  • getAllDocs(): Para recorrer e indexar todos los elementos. Se llama a este método una vez por cada recorrido programado.
  • (Opcional) getChanges(): Si tu repositorio admite la detección de cambios, anula este método para recuperar y, luego, indexar los elementos modificados.
  • (Opcional) close(): Para la limpieza del repositorio durante el cierre.

Cada método devuelve un objeto ApiOperation, que realiza la indexación con IndexingService.indexItem().

Obtén parámetros de configuración personalizados

Para controlar la configuración del conector, debes recuperar los parámetros personalizados del objeto Configuration. Realiza esta tarea en el método init() de la clase Repository.

La clase Configuration incluye métodos para recuperar diferentes tipos de datos. Cada método devuelve un objeto ConfigValue. Usa el método get() del objeto ConfigValue para recuperar el valor. En este fragmento de FullTraversalSample, se muestra cómo recuperar un valor entero personalizado:

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

Para recuperar y analizar parámetros con varios valores, usa uno de los analizadores de tipos de la clase Configuration. En este fragmento del conector del instructivo, se usa getMultiValue para recuperar una lista de nombres de repositorios de GitHub:

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

Realiza un recorrido completo

Anula getAllDocs() para realizar un recorrido completo. Este método acepta un punto de control para reanudar la indexación si se interrumpe. Para cada elemento:

  1. Establece permisos.
  2. Establece metadatos.
  3. Combínalos en un RepositoryDoc.
  4. Empaqueta cada elemento en el iterador que muestra getAllDocs().

Si el conjunto de elementos es demasiado grande para una sola llamada, usa un punto de control y llama a hasMore(true).

Establece los permisos para un elemento

Los repositorios usan listas de control de acceso (LCA) para identificar a los usuarios o grupos con acceso a un elemento. En una LCA, se enumeran los IDs de los usuarios o grupos autorizados.

Para garantizar que los usuarios solo vean los resultados de la búsqueda a los que tienen autorización para acceder, debes replicar las LCA de tu repositorio. Incluye la LCA cuando indexes un elemento para que Google Cloud Search pueda proporcionar el nivel de acceso correcto.

El SDK de Content Connector incluye clases y métodos para modelar las LCA de la mayoría de los repositorios. Analiza las LCA de tu repositorio y crea las LCA correspondientes para Cloud Search durante la indexación. El modelado de ACL complejas, como las que usan herencia, requiere una planificación cuidadosa. Para obtener más información, consulta LCA de Cloud Search.

Usa la clase Acl.Builder para establecer el acceso. Este fragmento del ejemplo de recorrido completo permite que todos los usuarios del dominio (getCustomerPrincipal()) lean todos los elementos (setReaders()):

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

Para modelar correctamente las LCA del repositorio, en especial las que usan modelos de herencia, se requiere la información que se encuentra en LCA de Cloud Search.

Establece los metadatos de un elemento

Los metadatos se almacenan en un objeto Item. Para crear un Item, necesitas un ID único, un tipo de elemento, una LCA, una URL y una versión. Usa la clase de asistente 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 el elemento indexable

Usa la clase RepositoryDoc.Builder.

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 es un ApiOperation que realiza la solicitud de IndexingService.indexItem().

Usa el método setRequestMode() de la clase RepositoryDoc.Builder para establecer la solicitud de indexación en ASYNCHRONOUS o SYNCHRONOUS:

ASYNCHRONOUS
Este modo tiene una latencia de indexación a entrega más prolongada, pero admite una cuota de capacidad de procesamiento más grande. Usa el modo asíncrono para la indexación inicial (reabastecimiento) de un repositorio completo.
SYNCHRONOUS
Este modo tiene una latencia de indexación a entrega más corta, pero una cuota de capacidad de procesamiento más pequeña. Usa el modo síncrono para indexar las actualizaciones y los cambios del repositorio. Si no se especifica, el modo de solicitud predeterminado es SYNCHRONOUS.
Empaqueta cada elemento indexable en un iterador

El método getAllDocs() devuelve un CheckpointCloseableIterable de objetos RepositoryDoc. Usa la clase CheckpointCloseableIterableImpl.Builder.

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

Próximos pasos

Crea un conector de recorrido de lista mediante una clase de plantilla

La cola de indexación de Cloud Search contiene IDs y hashes opcionales para los elementos del repositorio. Un conector de recorrido de lista envía IDs a esta cola y los recupera para la indexación. Cloud Search mantiene estas colas para determinar el estado de los elementos, como las eliminaciones. Consulta La cola de indexación de Cloud Search.

En esta sección, se hace referencia a ListTraversalSample.

Implementa el punto de entrada del conector

El método main() crea una instancia de Application y llama a start(). Usa IndexingApplication.Builder para crear una instancia de la plantilla ListingConnector.

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

Implementa la interfaz Repository

Anula los siguientes métodos para ListingConnector:

  • init(): Para la configuración del repositorio.
  • getIds(): Para recuperar los IDs y los hashes de todos los registros
  • getDoc(): Para agregar, actualizar o borrar elementos del índice
  • getChanges(): Para actualizaciones incrementales con detección de cambios (opcional).
  • close() (opcional): Para la limpieza del repositorio.

Realiza el recorrido de lista

Anula getIds() para recuperar IDs y hashes. Anula getDoc() para controlar cada elemento de la cola de indexación de Cloud Search.

Envía ID de elementos y valores hash

Anula getIds() para recuperar los IDs y los hashes de contenido. Empaquétalos en una solicitud de PushItems a la cola de indexación.

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

Usa PushItems.Builder para empaquetar los IDs y los hashes.

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

Anula getDoc() para controlar los elementos de la cola de indexación. Los elementos pueden ser nuevos, modificados, sin cambios o borrados.

  1. Comprueba si el ID del elemento existe en el repositorio. De lo contrario, bórralo.
  2. Sondea el índice para obtener el estado. Si no se modificó (ACCEPTED), no hagas nada.
  3. Indexa los elementos nuevos o modificados: establece permisos, configura metadatos, combina en un RepositoryDoc y devuélvelo.
Controla los elementos borrados

En este fragmento, se muestra cómo determinar si un elemento existe y cómo borrarlo si no es así.

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);
}
Controla elementos no modificados

Consulta la cola de indexación para controlar los elementos no modificados.

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

En el ejemplo, se usa un hash para detectar cambios.

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);
}
Establece los permisos para un elemento

Los repositorios usan listas de control de acceso (LCA) para identificar a los usuarios o grupos con acceso a un elemento. En una LCA, se enumeran los IDs de los usuarios o grupos autorizados.

Para garantizar que los usuarios solo vean los resultados de la búsqueda a los que tienen autorización para acceder, debes replicar las LCA de tu repositorio. Incluye la LCA cuando indexes un elemento para que Google Cloud Search pueda proporcionar el nivel de acceso correcto.

El SDK de Content Connector incluye clases y métodos para modelar las LCA de la mayoría de los repositorios. Analiza las LCA de tu repositorio y crea las LCA correspondientes para Cloud Search durante la indexación. El modelado de ACL complejas, como las que usan herencia, requiere una planificación cuidadosa. Para obtener más información, consulta LCA de Cloud Search.

Usa la clase Acl.Builder para establecer el acceso. Este fragmento del ejemplo de recorrido completo permite que todos los usuarios del dominio (getCustomerPrincipal()) lean todos los elementos (setReaders()):

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

Para modelar correctamente las LCA del repositorio, en especial las que usan modelos de herencia, se requiere la información que se encuentra en LCA de Cloud Search.

Establece los metadatos de un elemento
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 indexable
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();

Usa el método setRequestMode() de la clase RepositoryDoc.Builder para establecer la solicitud de indexación en ASYNCHRONOUS o SYNCHRONOUS:

ASYNCHRONOUS
Este modo tiene una latencia de indexación a entrega más prolongada, pero admite una cuota de capacidad de procesamiento más grande. Usa el modo asíncrono para la indexación inicial (reabastecimiento) de un repositorio completo.
SYNCHRONOUS
Este modo tiene una latencia de indexación a entrega más corta, pero una cuota de capacidad de procesamiento más pequeña. Usa el modo síncrono para indexar las actualizaciones y los cambios del repositorio. Si no se especifica, el modo de solicitud predeterminado es SYNCHRONOUS.

Próximos pasos

Aquí hay algunos pasos que puedes seguir:

  • Implementa el método close() para liberar cualquier recurso antes de finalizar el procedimiento (opcional).
  • Crea un conector de identidad mediante el SDK de Content Connector (opcional).

Crea un conector de recorrido de grafo mediante una clase de plantilla

La cola de indexación de Cloud Search contiene IDs y valores hash opcionales para cada elemento del repositorio. Un conector de recorrido de grafo envía los IDs de elementos a la cola de indexación de Google Cloud Search y los recupera uno por uno para la indexación. Google Cloud Search mantiene colas y compara contenidos de cola para determinar el estado del elemento, por ejemplo, si un elemento se ha borrado del repositorio. Para obtener más información sobre la cola de indexación de Cloud Search, consulta La cola de indexación de Google Cloud Search.

Durante la indexación, el contenido del elemento se recupera del repositorio de datos y cualquier ID del elemento secundario se envía a la cola. El conector procesa de forma recursiva los IDs principales y secundarios hasta que se controlan todos los elementos.

Implementa el punto de entrada del conector

El punto de entrada a un conector es el método main(). Este método crea una instancia de la clase Application y llama a su método start() para ejecutar el conector.

Antes de llamar a application.start(), usa la clase IndexingApplication.Builder para crear una instancia de la plantilla ListingConnector. El objeto ListingConnector acepta un objeto Repository cuyos métodos implementarás.

Implementa la interfaz Repository

Anula init(), getIds(), getDoc() y, de manera opcional, getChanges() o close().

Realiza el recorrido de grafo

Anula getIds() para recuperar los IDs iniciales y getDoc() para controlar los elementos y enviar los IDs secundarios a la cola.

Envía ID de elementos y valores hash
GraphTraversalSample.java
PushItems.Builder allIds = new PushItems.Builder();
PushItem item = new PushItem();
allIds.addPushItem("root", item);
Recupera y controla cada elemento
  1. Comprueba si el ID existe en el repositorio. Si no es así, borra el elemento.
  2. En el caso de los elementos existentes, establece permisos y metadatos, y combínalos en un RepositoryDoc.
  3. Envía los IDs secundarios a la cola de indexación.
  4. Devuelve el RepositoryDoc.
Controla los elementos borrados
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);
Establece los metadatos y crea el elemento
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();
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);
Coloca los IDs secundarios en la cola de indexación
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();

Crea un conector de contenido con la API de REST

Las siguientes secciones explican cómo crear un conector de contenido con la API de REST.

Determina tu estrategia de recorrido

Las estrategias (Completa, Lista y Gráfico) son conceptualmente las mismas que para el SDK. Implementa la estrategia que elegiste con la API de REST.

Implementa tu estrategia de recorrido y los elementos de índice

Registra tu esquema y, luego, propaga el índice con lo siguiente:

  1. items.upload para archivos de más de 100 KiB (opcional)
  2. media.upload (opcional) para archivos multimedia
  3. items.index para indexar el elemento.

    Ejemplo de solicitud de indexación:

    {
      "name": "datasource/<data_source_id>/items/titanic",
      "acl": {
        "readers": [
          {
            "gsuitePrincipal": {
              "gsuiteDomain": true
            }
          }
        ]
      },
      "metadata": {
        "title": "Titanic",
        "viewUrl": "http://www.imdb.com/title/tt2234155/",
        "objectType": "movie"
      },
      "structuredData": {
        "object": {
          "properties": [
            {
              "name": "movieTitle",
              "textValues": { "values": ["Titanic"] }
            }
          ]
        }
      },
      "content": {
        "inlineContent": "A seventeen-year-old aristocrat falls in love...",
        "contentFormat": "TEXT"
      },
      "version": "01",
      "itemType": "CONTENT_ITEM"
    }
    
  4. Opcional: Usa items.get para verificar la indexación.

Maneja cambios en el repositorio

Vuelve a indexar periódicamente todo el repositorio para realizar una indexación completa. Para el recorrido de listas o grafos, usa la cola de indexación de Google Cloud para hacer un seguimiento de los cambios y solo indexar lo que se modificó. Usa items.push para agregar elementos a la fila.