Crear un conector de contenido

Un conector de contenido es un programa de software que se utiliza para hacer un barrido de los datos del repositorio de una empresa y transferirlos a una fuente de datos. Google ofrece las siguientes opciones para desarrollar conectores de contenido:

  • El SDK Content Connector. Esta opción es muy adecuada si programas en Java. El SDK Content Connector es un envoltorio de la API REST que permite crear conectores rápidamente. Para obtener más información, consulta el apartado Crear un conector de contenido con el SDK Content Connector.

  • Una API REST de nivel bajo o bibliotecas de API. Usa estas opciones si no programas en Java o si tu base de código se ajusta más al uso de una API REST o una biblioteca. Para obtener más información, consulta el apartado Crear un conector de contenido con la API REST.

Un conector de contenido estándar realiza las siguientes tareas:

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

Crear un conector de contenido con el SDK Content Connector

En las siguientes secciones te explicamos cómo crear un conector de contenido con el SDK Content Connector.

Descargar e instalar el SDK Content Connector

Si quieres instalar el SDK Content Connector, deberás tener Maven en el ordenador. Para instalar el SDK Content Connector:

  1. Descarga el SDK Content Connector.

  2. Desde la línea de comandos, descomprime el archivo que has descargado. Se creará un directorio del SDK Content Connector.

  3. En ese directorio, usa los siguientes comandos para instalar los distintos componentes del 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

Configurar dependencias

Para usar el SDK, debes incluir determinadas dependencias en el archivo de compilación. Haz clic en una de las pestañas que se muestran a continuación para ver las dependencias de tu entorno de compilación:

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'

Crear la configuración del conector

Todos los conectores incluyen un archivo de configuración que contiene los parámetros que utilizan, como el ID de tu repositorio. Los parámetros se definen como pares clave-valor, como en el ejemplo siguiente:

api.sourceId=1234567890abcdef
.

El SDK de Google Cloud Search contiene varios parámetros de configuración proporcionados por Google que se utilizan en todos los conectores. Debes declarar los siguientes parámetros proporcionados por Google en tu archivo de configuración:

  • Si se trata de un conector de contenido, deberás declarar api.sourceId y api.serviceAccountPrivateKeyFile, ya que estos parámetros identifican la ubicación de tu repositorio y la clave privada necesaria para acceder a él.
  • Si se trata de un conector de identidades, deberás declarar api.identitySourceId, ya que este parámetro identifica la ubicación de tu fuente de identidad externa. Si vas a sincronizar cuentas de usuario, también deberás declarar api.customerId como ID único de la cuenta de G Suite de tu empresa.

A menos que quieras anular los valores predeterminados de otros parámetros proporcionados por Google, no tendrás que declararlos en el archivo de configuración. Para obtener más información sobre los parámetros facilitados por Google (por ejemplo, si quieres ver instrucciones sobre cómo crear determinados ID y claves), consulta el capítulo sobre parámetros de configuración proporcionados por Google.

También puedes definir tus propios parámetros específicos del repositorio para usarlos en el archivo de configuración.

Nota: Aunque no hay ningún requisito estricto sobre la nomenclatura del archivo de propiedades del conector, te recomendamos que lo guardes con la extensión .properties o .config.

Enviar el archivo de configuración al conector

Para enviar el archivo de configuración al conector, define la propiedad del sistema config. Puedes definir esta propiedad utilizando el argumento -D al iniciar el conector. Por ejemplo, el siguiente comando inicia el conector con el archivo de configuración MyConfig.properties:

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

Si falta este argumento, el SDK intentará acceder a un archivo de configuración predeterminado denominado connector-config.properties.

Determinar la estrategia de barrido

La función principal de un conector de contenido es hacer un barrido del contenido de un repositorio e indexar sus datos. Debes implementar una estrategia de barrido basada en el tamaño y la distribución de los datos de tu repositorio. Puedes diseñar tu propia estrategia o elegir una de las que se implementan en el SDK:

Estrategia de barrido completo

Una estrategia de barrido completo analiza todo el repositorio e indexa todos los elementos de forma indiscriminada. Esta estrategia se usa generalmente cuando el tamaño del repositorio es pequeño, por lo que se puede hacer un barrido completo cada vez que se indexa el contenido sin que suponga una sobrecarga.

Esta estrategia de barrido es adecuada en repositorios pequeños donde la mayoría de los datos son estáticos y no jerárquicos. También se puede usar cuando la detección de cambios resulta difícil o no se admite en el repositorio.

Estrategia de barrido de listas

Una estrategia de barrido de listas analiza el repositorio completo, incluidos todos los nodos secundarios, y determina el estado de cada elemento. A continuación, el conector realiza una segunda pasada y solo indexa los elementos que sean nuevos o se hayan actualizado desde la última indexación. Esta estrategia se usa generalmente para realizar actualizaciones incrementales en un índice ya existente (en lugar de hacer un barrido completo cada vez que se actualiza el índice).

Esta estrategia de barrido resulta adecuada cuando la detección de cambios resulta difícil o no se admite en el repositorio, o si tienes datos no jerárquicos y trabajas con conjuntos de datos muy grandes.

Barrido de gráficos

Una estrategia de barrido de gráficos analiza todo el nodo principal para determinar el estado de cada elemento. A continuación, el conector realiza una segunda pasada y solo indexa los elementos del nodo raíz que sean nuevos o se hayan actualizado desde la última indexación. Por último, el conector envía todos los ID secundarios e indexa los elementos de los nodos secundarios que sean nuevos o se hayan actualizado. El conector repite el procedimiento con todos los nodos secundarios hasta que se procesan todos los elementos. Este tipo de barrido se hace normalmente en repositorios jerárquicos, donde no resulta práctico crear listas de todos los ID.

Esta estrategia resulta adecuada si tienes datos jerárquicos que deben rastrearse, como una serie de directorios o páginas web.

Todas estas estrategias de barrido se implementan mediante una clase de conector que se facilita como una plantilla del SDK. Aunque puedes implementar tu propia estrategia de barrido, con estas plantillas podrás agilizar notablemente las tareas de desarrollo del conector. Para crear un conector mediante una plantilla, ve a la sección correspondiente a tu estrategia de barrido:

Crear un conector de barrido completo con una clase que se facilita como plantilla

En esta sección de los documentos se hace referencia a fragmentos de código del ejemplo FullTraversalSample.

Implementar el punto de entrada del conector

El punto de entrada a un conector es el método main(). La tarea principal de este método es crear una instancia de la clase Application y hacer una llamada a su método start() para ejecutar el conector.

Antes de hacer una llamada a application.start(), usa la clase IndexingApplication.Builder para crear una instancia de la plantilla FullTraversalConnector. La plantilla FullTraversalConnector acepta un objeto Repository que contiene los métodos que vas a implementar. En el siguiente fragmento de código se muestra cómo implementar el método 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 segundo plano, el SDK realiza una llamada al método initConfig() después de que el método main() de tu conector haga una llamada a Application.build. El método initConfig() realiza las siguientes tareas:

  1. Hace una llamada al método Configuation.isInitialized() para asegurarse de que el objeto Configuration no se haya inicializado.
  2. Inicializa un objeto Configuration con los pares clave-valor proporcionados por Google. Cada par clave-valor se almacena en un objeto ConfigValue dentro del objeto Configuration.

Implementar la interfaz Repository

El único fin del objeto Repository es hacer el barrido y la indexación de los elementos del repositorio. Al usar una plantilla, solo tienes que anular ciertos métodos incluidos en la interfaz Repository para crear un conector de contenido. Los métodos que se anulan dependerán de la plantilla y la estrategia de barrido que utilices. Si utilizas FullTraversalConnector, anula los siguientes métodos:

  • Método init(). Para realizar cualquier configuración e inicialización del repositorio de datos, anula el método init().

  • Método getAllDocs(). Para hacer un barrido e indexar todos los elementos del repositorio de datos, anula el método getAllDocs(). Se realiza una llamada a este método en cada barrido programado (según se haya definido en la configuración).

  • (Opcional) Método getChanges(). Si tu repositorio admite la detección de cambios, anula el método getChanges(). Se realiza una llamada a este método en cada barrido incremental programado (según se haya definido en la configuración) para obtener los elementos modificados e indexarlos.

  • (Opcional) Método close(). Si tienes que realizar una limpieza del repositorio, anula el método close(). Se realiza una llamada a este método al cerrar el conector.

Cada uno de los métodos del objeto Repository devuelve algún tipo de objeto ApiOperation. Un objeto ApiOperation realiza una acción mediante una o varias llamadas a IndexingService.indexItem() para llevar a cabo la indexación del repositorio.

Obtener parámetros de configuración personalizados

Cuando definas la configuración del conector, tendrás que obtener los parámetros personalizados del objeto Configuration. Esta tarea generalmente se realiza en el método init() de una clase Repository.

La clase Configuration contiene varios métodos para obtener diferentes tipos de datos de una configuración. Cada método devuelve un objeto ConfigValue. Deberás usar el método get() del objeto ConfigValue para obtener el valor real. En el siguiente fragmento, de FullTraversalSample, se muestra cómo obtener un valor entero personalizado de un objeto Configuration:

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

Si quieres obtener y analizar un parámetro que contenga varios valores, usa uno de los analizadores de tipos de la clase Configuration para analizar los datos en fragmentos separados. El siguiente fragmento, del conector del tutorial, usa el método getMultiValue para obtener una lista de nombres de repositorios de GitHub:

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

Hacer un barrido completo

Anula getAllDocs() para hacer un barrido completo e indexar el repositorio. El método getAllDocs() acepta un punto de control. El punto de control se utiliza para continuar la indexación en un elemento específico en caso de que se interrumpa el proceso. Con cada elemento del repositorio, lleva a cabo estos pasos en el método getAllDocs():

  1. Define los permisos.
  2. Define los metadatos del elemento que vas a indexar.
  3. Agrupa los metadatos y el elemento en un RepositoryDoc indexable.
  4. Empaqueta cada elemento indexable en un iterador devuelto por el método getAllDocs(). Ten en cuenta que getAllDocs() devuelve un objeto CheckpointCloseableIterable, que es una iteración de objetos ApiOperation, cada uno de los cuales representa una solicitud a API realizada en un RepositoryDoc (por ejemplo, indexarlo).

Si el conjunto de elementos es demasiado grande para procesarlo mediante una sola llamada, incluye un punto de control y define hasMore(true) para indicar que hay más elementos que se pueden incluir en la indexación.

Definir los permisos de un elemento

El repositorio utiliza una Lista de control de acceso (LCA) para identificar a los usuarios o grupos que tienen acceso a un elemento. Una LCA es una lista de los ID de los grupos o usuarios que pueden acceder al elemento.

Debes duplicar esta LCA en la fuente de datos para asegurarte de que solo los usuarios con acceso a un elemento puedan verlo en los resultados de búsqueda. Cuando se indexa un elemento, debe incluirse su LCA para que Google Cloud Search tenga la información que necesita para proporcionar el nivel correcto de acceso a dicho elemento.

El SDK Content Connector proporciona un amplio conjunto de clases y métodos para diseñar las LCA de la mayoría de los repositorios. Cuando indexes un elemento, debes analizar la LCA de cada elemento del repositorio y crear una LCA correspondiente para Google Cloud Search. Si la LCA del repositorio utiliza conceptos como herencia de LCAs, el proceso de diseño puede resultar complejo. Para obtener más información, consulta el capítulo sobre LCAs de Google Cloud Search.

Nota: La API Indexing de Cloud Search admite LCAs de un solo dominio, pero no de varios dominios. Fundamentalmente, deberás usar la clase Acl.Builder para definir el acceso a cada elemento mediante una LCA. El siguiente fragmento de código, tomado de la muestra de barrido completo, permite a todos los usuarios o "principales" (getCustomerPrincipal()) ser "lectores" de todos los elementos (.setReaders()) cuando se realiza una búsqueda.

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

Para poder diseñar correctamente las LCA de la fuente de datos, necesitarás saber cómo funcionan. Por ejemplo, podrías estar indexando archivos en un sistema de archivos que utiliza algún tipo de modelo de herencia por el cual las carpetas secundarias heredan permisos de las principales. Para diseñar el sistema de herencia de LCAs se requiere cierta información adicional, que se aborda en el capítulo sobre LCAs de Google Cloud Search.

Definir los metadatos de un elemento

Los metadatos se almacenan en un objeto Item. Para crear un objeto Item, necesitas como mínimo un ID de cadena único, un tipo de elemento, una LCA, una URL y una versión del elemento. El siguiente fragmento de código muestra cómo crear un Item utilizando la clase de ayuda 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();

Crear el elemento indexable

Una vez que hayas definido los metadatos del elemento, podrás crear el elemento indexable propiamente dicho utilizando la clase RepositoryDoc.Builder. El siguiente ejemplo muestra cómo crear un elemento indexable.

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 tipo de ApiOperation que realiza la solicitud IndexingService.indexItem() propiamente dicha.

También puedes usar el método setRequestMode() de la clase RepositoryDoc.Builder para identificar la solicitud de indexación como ASYNCHRONOUS o SYNCHRONOUS:

ASYNCHRONOUS
Con el modo asíncrono se consigue una latencia de indexación a servicio más larga y una alta cuota de rendimiento en las solicitudes de indexación. Este modo es aconsejable en la indexación inicial (reposición) del repositorio completo.
SYNCHRONOUS
Con el modo síncrono se consigue una latencia de indexación a servicio más corta y una cuota de rendimiento limitada. Este modo es aconsejable en la indexación de actualizaciones y cambios realizados en el repositorio. Si se deja sin especificar, el modo de solicitud predeterminado es SYNCHRONOUS.

Empaquetar cada elemento indexable en un iterador

El método getAllDocs() devuelve un Iterator, en concreto un CheckpointCloseableIterable, de los objetos RepositoryDoc. Puedes utilizar la clase CheckpointClosableIterableImpl.Builder para crear y devolver un iterador. El siguiente fragmento de código muestra cómo crear y devolver un iterador.

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

El SDK ejecuta todas las llamadas de indexación incluidas en el iterador.

Pasos siguientes

Estos son algunos pasos que puedes seguir a continuación:

Crear un conector de barrido de listas con una clase que se facilita como plantilla

El conector de barrido de listas envía IDs de elementos a una cola de indexación de Cloud Search y los recupera uno a uno para indexarlos. La cola de indexación de Cloud Search se utiliza para alojar IDs y valores de hash opcionales de cada elemento del repositorio. Google Cloud Search mantiene colas y compara los contenidos de estas para determinar el estado de los elementos; por ejemplo, si se ha eliminado un elemento del repositorio. Para obtener más información, consulta el capítulo Cola de indexación de Google Cloud Search.

En esta sección de los documentos se hace referencia a fragmentos de código del ejemplo ListTraversalSample.

Implementar el punto de entrada del conector

El punto de entrada a un conector es el método main(). La tarea principal de este método es crear una instancia de la clase Application y hacer una llamada a su método start() para ejecutar el conector.

Antes de realizar una llamada a application.start(), usa la clase IndexingApplication.Builder para crear una instancia de la plantilla ListingConnector. La plantilla ListingConnector acepta un objeto Repository que contiene los métodos que vas a implementar. En el siguiente fragmento de código se muestra cómo crear una instancia de ListingConnector y de su Repository asociado:

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 segundo plano, el SDK realiza una llamada al método initConfig() después de que el método main() de tu conector haga una llamada a Application.build. El método initConfig():

  1. Hace una llamada al método Configuation.isInitialized() para asegurarse de que el objeto Configuration no se haya inicializado.
  2. Inicializa un objeto Configuration con los pares clave-valor proporcionados por Google. Cada par clave-valor se almacena en un objeto ConfigValue dentro del objeto Configuration.

Implementar la interfaz Repository

El único fin del objeto Repository es hacer un barrido e indexación de los elementos del repositorio. Al usar una plantilla, solo tienes que anular ciertos métodos incluidos en la interfaz Repository para crear un conector de contenido. Los métodos que se anulan dependerán de la plantilla y la estrategia de barrido que utilices. Para ListingConnector, anula los siguientes métodos:

  • Método init(). Para realizar cualquier configuración e inicialización del repositorio de datos, anula el método init().

  • Método getIds(). Para recuperar los ID y los valores de hash de todos los registros del repositorio, anula el método getIds().

  • Método getDoc(). Para añadir, actualizar, modificar o eliminar elementos del índice, anula el método getDoc().

  • (Opcional) Método getChanges(). Si tu repositorio admite la detección de cambios, anula el método getChanges(). Se realiza una llamada a este método en cada barrido incremental programado (según se haya definido en la configuración) para obtener los elementos modificados e indexarlos.

  • (Opcional) Método close(). Si tienes que realizar una limpieza del repositorio, anula el método close(). Se realiza una llamada a este método al cerrar el conector.

Cada uno de los métodos del objeto Repository devuelve algún tipo de objeto ApiOperation. Un objeto ApiOperation realiza una acción mediante una o varias llamadas a IndexingService.indexItem() para llevar a cabo la indexación del repositorio.

Obtener parámetros de configuración personalizados

Cuando definas la configuración del conector, tendrás que obtener los parámetros personalizados del objeto Configuration. Esta tarea generalmente se realiza en el método init() de una clase Repository.

La clase Configuration contiene varios métodos para obtener diferentes tipos de datos de una configuración. Cada método devuelve un objeto ConfigValue. Deberás usar el método get() del objeto ConfigValue para obtener el valor real. En el siguiente fragmento, de FullTraversalSample, se muestra cómo obtener un valor entero personalizado de un objeto Configuration:

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

Si quieres obtener y analizar un parámetro que contenga varios valores, usa uno de los analizadores de tipos de la clase Configuration para analizar los datos en fragmentos separados. El siguiente fragmento, del conector del tutorial, usa el método getMultiValue para obtener una lista de nombres de repositorios de GitHub:

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

Hacer un barrido de listas

Anula el método getIds() para recuperar los ID y valores de hash en todos los registros del repositorio. El método getIds() acepta un punto de control, que se utiliza para continuar la indexación en un elemento específico en caso de que se interrumpa el proceso.

A continuación, anula el método getDoc() para tratar cada elemento de la cola de indexación de Cloud Search.

Enviar IDs de elementos y valores de hash

Anula getIds() para obtener los ID de elementos y sus valores de hash de contenido asociados del repositorio. A continuación, los pares de ID y valor de hash se empaquetan en una solicitud de operación de envío a la cola de indexación de Cloud Search. Por lo general, los ID raíz o principales se envían primero, seguidos de los ID secundarios hasta que se haya procesado la jerarquía completa de los elementos.

El método getIds() acepta un punto de control, que representa el último elemento que se indexará. El punto de control se puede utilizar para continuar la indexación en un elemento específico en caso de que se interrumpa el proceso. Con cada elemento del repositorio, lleva a cabo estos pasos en el método getIds():

  • Obtén cada ID de elemento y el valor de hash asociado del repositorio.
  • Empaqueta cada par de ID y valor de hash en un PushItems.
  • Combina cada elemento PushItems en un iterador devuelto por el método getIds(). Ten en cuenta que getIds() devuelve un objeto CheckpointCloseableIterable, que es una iteración de objetos ApiOperation, cada uno de los cuales representa una solicitud a API realizada en un RepositoryDoc (por ejemplo, enviar los elementos a la cola).

El siguiente fragmento de código muestra cómo obtener los ID de elemento y los valores de hash e insertarlos en un PushItem. Un PushItems. es una solicitud de ApiOperation de enviar un elemento a la cola de indexación de 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);
}

El siguiente fragmento de código muestra cómo usar los elementos de la clase PushItems.Builder para empaquetar los ID y los valores de hash en un único envío ApiOperation.

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

Los elementos se envían a la cola de indexación de Cloud Search para su posterior procesamiento.

Recuperar y tratar cada elemento

Anula getDoc() para tratar cada elemento de la cola de indexación de Cloud Search. Los elementos del repositorio de origen se pueden añadir, modificar, mantener sin cambios o eliminar. Recupera e indexa todos los elementos que sean nuevos o se hayan modificado. Elimina del índice los elementos que ya no existan en el repositorio de origen.

El método getDoc() acepta un elemento de la cola de indexación de Google Cloud Search. Con cada elemento en la cola, lleva a cabo estos pasos en el método getDoc():

  1. Comprueba si el ID del elemento, dentro de la cola de indexación de Google Cloud Search, figura en el repositorio. Si no estuviera presente, elimina el elemento del índice.

  2. Consulta el estado de elementos del índice y, en caso de que un elemento no se haya modificado (ACCEPTED), no hagas nada.

  3. Si el índice ha cambiado o contiene elementos nuevos:

    1. Define los permisos.
    2. Define los metadatos del elemento que vas a indexar.
    3. Agrupa los metadatos y el elemento en un RepositoryDoc indexable.
    4. Devuelve el RepositoryDoc.

Tratar los elementos eliminados

El siguiente fragmento de código muestra cómo determinar si un elemento existe en el repositorio y, de no ser así, 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);
}

Ten en cuenta que documents es una estructura de datos que representa el repositorio. Si documentID no se encuentra en documents, devuelve APIOperations.deleteItem(resourceName) para eliminar el elemento del índice.

Tratar los elementos que no han cambiado

El siguiente fragmento de código muestra cómo consultar el estado de los elementos en la cola de indexación de Google Cloud Search y cómo tratar un elemento que no ha cambiado.

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

Para determinar si el elemento no se ha modificado, consulta su estado y otros metadatos que puedan indicar que ha habido un cambio. En este ejemplo, el hash de metadatos se utiliza para determinar si el elemento ha cambiado.

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

Definir los permisos de un elemento

El repositorio utiliza una Lista de control de acceso (LCA) para identificar a los usuarios o grupos que tienen acceso a un elemento. Una LCA es una lista de los ID de los grupos o usuarios que pueden acceder al elemento.

Debes duplicar esta LCA en la fuente de datos para asegurarte de que solo los usuarios con acceso a un elemento puedan verlo en los resultados de búsqueda. Cuando se indexa un elemento, debe incluirse su LCA para que Google Cloud Search tenga la información que necesita para proporcionar el nivel correcto de acceso a dicho elemento.

El SDK Content Connector proporciona un amplio conjunto de clases y métodos para diseñar las LCA de la mayoría de los repositorios. Cuando indexes un elemento, debes analizar la LCA de cada elemento del repositorio y crear una LCA correspondiente para Google Cloud Search. Si la LCA del repositorio utiliza conceptos como herencia de LCAs, el proceso de diseño puede resultar complejo. Para obtener más información, consulta el capítulo sobre LCAs de Google Cloud Search.

Nota: La API Indexing de Cloud Search admite LCAs de un solo dominio, pero no de varios dominios. Fundamentalmente, deberás usar la clase Acl.Builder para definir el acceso a cada elemento mediante una LCA. El siguiente fragmento de código, tomado de la muestra de barrido completo, permite a todos los usuarios o "principales" (getCustomerPrincipal()) ser "lectores" de todos los elementos (.setReaders()) cuando se realiza una búsqueda.

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

Para poder diseñar correctamente las LCA de la fuente de datos, necesitarás saber cómo funcionan. Por ejemplo, podrías estar indexando archivos en un sistema de archivos que utiliza algún tipo de modelo de herencia por el cual las carpetas secundarias heredan permisos de las principales. Para diseñar el sistema de herencia de LCAs se requiere cierta información adicional, que se aborda en el capítulo sobre LCAs de Google Cloud Search.

Definir los metadatos de un elemento

Los metadatos se almacenan en un objeto Item. Para crear un objeto Item, necesitas como mínimo un ID de cadena único, un tipo de elemento, una LCA, una URL y una versión del elemento. El siguiente fragmento de código muestra cómo crear un Item utilizando la clase de ayuda 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();

Crear un elemento indexable

Una vez que hayas definido los metadatos del elemento, podrás crear el elemento indexable propiamente dicho utilizando la clase RepositoryDoc.Builder. El siguiente ejemplo muestra cómo crear 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();

Un RepositoryDoc es un tipo de ApiOperation que realiza la solicitud IndexingService.indexItem() propiamente dicha.

También puedes usar el método setRequestMode() de la clase RepositoryDoc.Builder para identificar la solicitud de indexación como ASYNCHRONOUS o SYNCHRONOUS:

ASYNCHRONOUS
Con el modo asíncrono se consigue una latencia de indexación a servicio más larga y una alta cuota de rendimiento en las solicitudes de indexación. Este modo es aconsejable en la indexación inicial (reposición) del repositorio completo.
SYNCHRONOUS
Con el modo síncrono se consigue una latencia de indexación a servicio más corta y una cuota de rendimiento limitada. Este modo es aconsejable en la indexación de actualizaciones y cambios realizados en el repositorio. Si se deja sin especificar, el modo de solicitud predeterminado es SYNCHRONOUS.

Pasos siguientes

Estos son algunos pasos que puedes seguir a continuación:

Crear un conector de barrido de gráficos con una clase que se facilita como plantilla

El conector de barrido de gráficos envía IDs de elementos a una cola de indexación de Cloud Search y los recupera uno a uno para indexarlos. La cola de indexación de Cloud Search se utiliza para alojar IDs y valores de hash opcionales de cada elemento del repositorio. Google Cloud Search mantiene colas y compara los contenidos de estas para determinar el estado de los elementos; por ejemplo, si se ha eliminado un elemento del repositorio. Para obtener más información, consulta el capítulo Cola de indexación de Google Cloud Search.

Durante la indexación, se obtiene el contenido del elemento del repositorio de datos y cualquier ID de elemento secundario que se detecte se envía a la cola. El conector repite el procedimiento con todos los ID principales y secundarios hasta que se procesan todos los elementos.

En esta sección de los documentos se hace referencia a fragmentos de código del ejemplo GraphTraversalSample.

Implementar el punto de entrada del conector

El punto de entrada a un conector es el método main(). La tarea principal de este método es crear una instancia de la clase Application y hacer una llamada a su método start() para ejecutar el conector.

Antes de realizar una llamada a application.start(), usa la clase IndexingApplication.Builder para crear una instancia de la plantilla ListingConnector. La plantilla ListingConnector acepta un objeto Repository que contiene los métodos que vas a implementar.

En el siguiente fragmento de código se muestra cómo crear una instancia de ListingConnector y de su Repository asociado:

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 segundo plano, el SDK realiza una llamada al método initConfig() después de que el método main() de tu conector haga una llamada a Application.build. El método initConfig():

  1. Realiza una llamada al método Configuation.isInitialized() para asegurarse de que el objeto Configuration no se haya inicializado.
  2. Inicializa un objeto Configuration con los pares clave-valor proporcionados por Google. Cada par clave-valor se almacena en un objeto ConfigValue dentro del objeto Configuration.

Implementar la interfaz Repository

El único fin del objeto Repository es hacer un barrido e indexación de los elementos del repositorio. Al usar una plantilla, solo tienes que anular ciertos métodos incluidos en la interfaz Repository para crear un conector de contenido. Los métodos que se anulan dependerán de la plantilla y la estrategia de barrido que utilices. Para ListingConnector, anula los siguientes métodos:

  • Método init(). Para realizar cualquier configuración e inicialización del repositorio de datos, anula el método init().

  • Método getIds(). Para recuperar los ID y los valores de hash de todos los registros del repositorio, anula el método getIds().

  • Método getDoc(). Para añadir, actualizar, modificar o eliminar elementos del índice, anula el método getDoc().

  • (Opcional) Método getChanges(). Si tu repositorio admite la detección de cambios, anula el método getChanges(). Se realiza una llamada a este método en cada barrido incremental programado (según se haya definido en la configuración) para obtener los elementos modificados e indexarlos.

  • (Opcional) Método close(). Si tienes que realizar una limpieza del repositorio, anula el método close(). Se realiza una llamada a este método al cerrar el conector.

Cada uno de los métodos del objeto Repository devuelve algún tipo de objeto ApiOperation. Un objeto ApiOperation realiza una acción mediante una o varias llamadas a IndexingService.indexItem() para llevar a cabo la indexación del repositorio.

Obtener parámetros de configuración personalizados

Cuando crees la configuración del conector, tendrás que obtener los parámetros personalizados del objeto Configuration. Esta tarea generalmente se realiza en el método init() de una clase Repository.

La clase Configuration contiene varios métodos para obtener diferentes tipos de datos de una configuración. Cada método devuelve un objeto ConfigValue. Deberás usar el método get() del objeto ConfigValue para obtener el valor real. En el siguiente fragmento, de FullTraversalSample, se muestra cómo obtener un valor entero personalizado de un objeto Configuration:

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

Si quieres obtener y analizar un parámetro que contenga varios valores, usa uno de los analizadores de tipos de la clase Configuration para analizar los datos en fragmentos separados. El siguiente fragmento, del conector del tutorial, usa el método getMultiValue para obtener una lista de nombres de repositorios de GitHub:

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

Hacer un barrido de gráficos

Anula el método getIds() para recuperar los ID y valores de hash en todos los registros del repositorio. El método getIds() acepta un punto de control, que se utiliza para continuar la indexación en un elemento específico en caso de que se interrumpa el proceso.

A continuación, anula el método getDoc() para tratar cada elemento de la cola de indexación de Cloud Search.

Enviar IDs de elementos y valores de hash

Anula getIds() para obtener los ID de elementos y sus valores de hash de contenido asociados del repositorio. A continuación, los pares de ID y valor de hash se empaquetan en una solicitud de operación de envío a la cola de indexación de Cloud Search. Por lo general, los ID raíz o principales se envían primero, seguidos de los ID secundarios hasta que se haya procesado la jerarquía completa de los elementos.

El método getIds() acepta un punto de control, que representa el último elemento que se indexará. El punto de control se puede utilizar para continuar la indexación en un elemento específico en caso de que se interrumpa el proceso. Con cada elemento del repositorio, lleva a cabo estos pasos en el método getIds():

  • Obtén cada ID de elemento y el valor de hash asociado del repositorio.
  • Empaqueta cada par de ID y valor de hash en un PushItems.
  • Combina cada elemento PushItems en un iterador devuelto por el método getIds(). Ten en cuenta que getIds() devuelve un objeto CheckpointCloseableIterable, que es una iteración de objetos ApiOperation, cada uno de los cuales representa una solicitud a API realizada en un RepositoryDoc (por ejemplo, enviar los elementos a la cola).

El siguiente fragmento de código muestra cómo obtener los ID de elemento y los valores de hash e insertarlos en un PushItem. Un PushItems. es una solicitud de ApiOperation de enviar un elemento a la cola de indexación de Cloud Search.

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

El siguiente fragmento de código muestra cómo usar los elementos de la clase PushItems.Builder para empaquetar los ID y los valores de hash en un único envío ApiOperation.

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

Los elementos se envían a la cola de indexación de Cloud Search para su posterior procesamiento.

Recuperar y tratar cada elemento

Anula getDoc() para tratar cada elemento de la cola de indexación de Cloud Search. Los elementos del repositorio de origen se pueden añadir, modificar, mantener sin cambios o eliminar. Recupera e indexa todos los elementos que sean nuevos o se hayan modificado. Elimina del índice los elementos que ya no existan en el repositorio de origen.

El método getDoc() acepta un elemento de la cola de indexación de Google Cloud Search. Con cada elemento en la cola, lleva a cabo estos pasos en el método getDoc():

  1. Comprueba si el ID del elemento, dentro de la cola de indexación de Google Cloud Search, figura en el repositorio. Si no estuviera presente, elimina el elemento del índice. Si el elemento figura en el repositorio, ve al paso siguiente.

  2. Si el índice ha cambiado o contiene elementos nuevos:

    1. Define los permisos.
    2. Define los metadatos del elemento que vas a indexar.
    3. Agrupa los metadatos y el elemento en un RepositoryDoc indexable.
    4. Coloca los ID secundarios en la cola de indexación de Google Cloud Search para su posterior procesamiento.
    5. Devuelve el RepositoryDoc.

Tratar los elementos eliminados

El siguiente fragmento de código muestra cómo determinar si un elemento existe en el índice y, de no ser así, 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);

Definir los permisos de un elemento

El repositorio utiliza una Lista de control de acceso (LCA) para identificar a los usuarios o grupos que tienen acceso a un elemento. Una LCA es una lista de los ID de los grupos o usuarios que pueden acceder al elemento.

Debes duplicar esta LCA en la fuente de datos para asegurarte de que solo los usuarios con acceso a un elemento puedan verlo en los resultados de búsqueda. Cuando se indexa un elemento, debe incluirse su LCA para que Google Cloud Search tenga la información que necesita para proporcionar el nivel correcto de acceso a dicho elemento.

El SDK Content Connector proporciona un amplio conjunto de clases y métodos para diseñar las LCA de la mayoría de los repositorios. Debes analizar la LCA de cada elemento del repositorio y crear una LCA correspondiente para Google Cloud Search cuando indexes un elemento. Si la LCA del repositorio utiliza conceptos como herencia de LCAs, el proceso de diseño puede resultar complejo. Para obtener más información, consulta el apartado sobre LCAs de Google Cloud Search.

Nota: La API Indexing de Cloud Search admite LCAs de un solo dominio. No admite LCAs de varios dominios. Fundamentalmente, deberás usar la clase Acl.Builder para definir el acceso a cada elemento mediante una LCA. El siguiente fragmento de código, tomado de la muestra de barrido completo, permite a todos los usuarios o "principales" (getCustomerPrincipal()) ser "lectores" de todos los elementos (.setReaders()) cuando se realiza una búsqueda.

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

Para poder diseñar correctamente las LCA de la fuente de datos, necesitarás saber cómo funcionan. Por ejemplo, podrías estar indexando archivos en un sistema de archivos que utiliza algún tipo de modelo de herencia por el cual las carpetas secundarias heredan permisos de las principales. Para diseñar el sistema de herencia de LCAs se requiere cierta información adicional, que se aborda en el capítulo sobre LCAs de Google Cloud Search

Definir los metadatos de un elemento

Los metadatos se almacenan en un objeto Item. Para crear un objeto Item, necesitas como mínimo un ID de cadena único, un tipo de elemento, una LCA, una URL y una versión del elemento. El siguiente fragmento de código muestra cómo crear un Item utilizando la clase de ayuda 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();

Crear el elemento indexable

Una vez que hayas definido los metadatos del elemento, podrás crear el elemento indexable propiamente dicho utilizando la clase RepositoryDoc.Builder. El siguiente ejemplo muestra cómo crear un elemento indexable.

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

También puedes usar el método setRequestMode() de la clase RepositoryDoc.Builder para identificar la solicitud de indexación como ASYNCHRONOUS o SYNCHRONOUS:

ASYNCHRONOUS
Con el modo asíncrono se consigue una latencia de indexación a servicio más larga y una alta cuota de rendimiento en las solicitudes de indexación. Este modo es aconsejable en la indexación inicial (reposición) del repositorio completo.
SYNCHRONOUS
Con el modo síncrono se consigue una latencia de indexación a servicio más corta y una cuota de rendimiento limitada. Este modo es aconsejable en la indexación de actualizaciones y cambios realizados en el repositorio. Si se deja sin especificar, el modo de solicitud predeterminado es SYNCHRONOUS.

Colocar los ID secundarios en la cola de indexación de Google Cloud Search

El siguiente fragmento de código muestra cómo incluir en la cola los ID secundarios del elemento principal que se está procesando en ese momento. Estos ID se procesarán una vez que se haya indexado el elemento principal.

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

Pasos siguientes

Estos son algunos pasos que puedes seguir a continuación:

Crear un conector de contenido con la API REST

En las siguientes secciones se explica cómo crear un conector de contenido con la API REST.

Determinar la estrategia de barrido

La función principal de un conector de contenido es hacer un barrido del contenido de un repositorio e indexar sus datos. Debes implementar una estrategia de barrido basada en el tamaño y la distribución de los datos de tu repositorio. A continuación, se explican tres estrategias de barrido habituales:

Estrategia de barrido completo

Una estrategia de barrido completo analiza todo el repositorio e indexa todos los elementos de forma indiscriminada. Esta estrategia se usa generalmente cuando el tamaño del repositorio es pequeño, por lo que se puede hacer un barrido completo cada vez que se indexa el contenido sin que suponga una sobrecarga.

Esta estrategia de barrido es adecuada en repositorios pequeños donde la mayoría de los datos son estáticos y no jerárquicos. También se puede usar cuando la detección de cambios resulta difícil o no se admite en el repositorio.

Estrategia de barrido de listas

Una estrategia de barrido de listas analiza el repositorio completo, incluidos todos los nodos secundarios, y determina el estado de cada elemento. A continuación, el conector realiza una segunda pasada y solo indexa los elementos que sean nuevos o se hayan actualizado desde la última indexación. Esta estrategia se usa generalmente para realizar actualizaciones incrementales en un índice ya existente (en lugar de hacer un barrido completo cada vez que se actualiza el índice).

Esta estrategia de barrido resulta adecuada cuando la detección de cambios resulta difícil o no se admite en el repositorio, o si tienes datos no jerárquicos y trabajas con conjuntos de datos muy grandes.

Barrido de gráficos

Una estrategia de barrido de gráficos analiza todo el nodo principal para determinar el estado de cada elemento. A continuación, el conector realiza una segunda pasada y solo indexa los elementos del nodo raíz que sean nuevos o se hayan actualizado desde la última indexación. Por último, el conector envía todos los ID secundarios e indexa los elementos de los nodos secundarios que sean nuevos o se hayan actualizado. El conector repite el procedimiento con todos los nodos secundarios hasta que se procesan todos los elementos. Este tipo de barrido se utiliza normalmente en repositorios jerárquicos, donde no resulta práctico crear listas de todos los ID.

Esta estrategia resulta adecuada si tienes datos jerárquicos que deben rastrearse, como una serie de directorios o páginas web.

Implementar la estrategia de barrido y los elementos del índice

Cada elemento indexable de Google Cloud Search se denomina elemento en la API de Cloud Search. Un elemento puede ser un archivo, una carpeta, una línea de un archivo CSV o un registro de base de datos.

Una vez que se haya registrado tu esquema, tendrás estas opciones para rellenar el índice:

  1. Usar llamadas a items.get para obtener un elemento para indexar.
  2. Usar items.index para indexar el elemento. Por ejemplo, si tu esquema utiliza la definición de objeto de movie schema, una solicitud de indexación de un único elemento se llevaría a cabo, tal como se muestra a continuación:
{
  "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"
}

Para hacer un barrido completo, tendrías que reindexar periódicamente el repositorio completo. Si quieres hacer un barrido de listas o gráficos, deberás implementar código para gestionar los cambios del repositorio.

Gestionar los cambios del repositorio

Puedes obtener e indexar cada elemento de un repositorio periódicamente para realizar una indexación completa. Aunque una indexación completa permite garantizar que tu índice se mantiene actualizado, puede resultar costosa cuando se utilizan repositorios de gran tamaño o jerárquicos.

En lugar de usar llamadas al índice para indexar un repositorio completo con frecuencia, también puedes usar la cola de indexación de Google Cloud Search como mecanismo para controlar los cambios e indexar solo los elementos que hayan cambiado. Puedes usar las solicitudes items.push para enviar los elementos a la cola para su posterior consulta y actualización. Para obtener más información, consulta el capítulo sobre la cola de indexación de Google Cloud Search.

Para obtener más información sobre la API REST de Cloud Search, consulta el apartado API de Cloud Search.