Tworzenie łącznika treści

Łącznik treści to program, który służy do przeszukiwania danych w repozytorium przedsiębiorstwa i wypełniania źródła danych. Google udostępnia te opcje tworzenia łączników treści:

  • Pakiet SDK łącznika treści. Jest to dobre rozwiązanie, jeśli programujesz w języku Java. Pakiet SDK oprogramowania sprzęgającego treści to otoczka interfejsu API REST, która umożliwia szybkie tworzenie oprogramowania sprzęgającego. Aby utworzyć łącznik treści za pomocą pakietu SDK, zapoznaj się z artykułem Tworzenie łącznika treści za pomocą pakietu SDK Content Connector.

  • interfejs REST API niskiego poziomu lub biblioteki API. Skorzystaj z tych opcji, jeśli nie programujesz w języku Java lub jeśli baza kodu lepiej obsługuje interfejs REST API lub bibliotekę. Aby utworzyć oprogramowanie sprzęgające treści za pomocą interfejsu API REST, zapoznaj się z artykułem Tworzenie oprogramowania sprzęgającego treści za pomocą interfejsu API REST.

Typowy łącznik treści wykonuje te zadania:

  1. Odczytuje i przetwarza parametry konfiguracji.
  2. Pobiera z repozytorium treści innych firm oddzielne fragmenty danych, które można indeksować, zwane „elementami”.
  3. Łączy listy kontroli dostępu, metadane i dane treści w indeksowane elementy.
  4. Indeksuje elementy w źródle danych Cloud Search.
  5. (opcjonalnie) Odsłuchuje powiadomienia o zmianach z repozytorium treści zewnętrznych. Powiadomienia o zmianach są przekształcane w żądania indeksowania, aby zsynchronizować źródło danych Cloud Search z repozytorium innej firmy. Konektor wykonuje to zadanie tylko wtedy, gdy repozytorium obsługuje wykrywanie zmian.

Tworzenie oprogramowania sprzęgającego treści za pomocą pakietu SDK Content Connector

W sekcjach poniżej znajdziesz informacje o tym, jak utworzyć oprogramowanie sprzęgające treści za pomocą pakietu SDK oprogramowania sprzęgającego treści.

Konfigurowanie zależności

Aby korzystać z pakietu SDK, musisz uwzględnić w pliku kompilacji określone zależności. Kliknij kartę poniżej, aby wyświetlić zależności dla środowiska kompilacji:

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'

Tworzenie konfiguracji oprogramowania sprzęgającego

Każdy łącznik ma plik konfiguracyjny zawierający parametry używane przez łącznik, takie jak identyfikator repozytorium. Parametry są zdefiniowane jako pary klucz-wartość, np.api.sourceId=1234567890abcdef.

Pakiet SDK Google Cloud Search zawiera kilka dostarczonych przez Google parametrów konfiguracji, które są używane przez wszystkie oprogramowania sprzęgające. W pliku konfiguracyjnym musisz zadeklarować te parametry dostarczone przez Google:

  • W przypadku łącznika treści musisz zadeklarować parametry api.sourceIdapi.serviceAccountPrivateKeyFile, ponieważ identyfikują one lokalizację repozytorium i klucza prywatnego potrzebnego do uzyskania dostępu do repozytorium.
  • W przypadku łącznika tożsamości musisz zadeklarować api.identitySourceId, ponieważ ten parametr określa lokalizację zewnętrznego źródła tożsamości. Jeśli synchronizujesz użytkowników, musisz też zadeklarować api.customerId jako unikalny identyfikator konta Google Workspace Twojej firmy.

Jeśli nie chcesz zastępować domyślnych wartości innych parametrów dostarczonych przez Google, nie musisz deklarować ich w pliku konfiguracyjnym. Więcej informacji o parametrach konfiguracyjnych dostarczanych przez Google, np. o tym, jak generować określone identyfikatory i klucze, znajdziesz w artykule Parametry konfiguracyjne dostarczane przez Google.

Możesz też zdefiniować własne parametry specyficzne dla repozytorium, które będą używane w pliku konfiguracyjnym.

Przekazywanie pliku konfiguracji do oprogramowania sprzęgającego

Ustaw właściwość systemową config, aby przekazać plik konfiguracji do łącznika. Usługę możesz ustawić za pomocą argumentu -D podczas uruchamiania złącza. Na przykład to polecenie uruchamia łącznik z plikiem konfiguracyjnym MyConfig.properties:

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

Jeśli tego argumentu brakuje, pakiet SDK próbuje uzyskać dostęp do domyślnego pliku konfiguracyjnego o nazwie connector-config.properties.

Określ strategię przechodzenia

Główną funkcją łącznika treści jest przeszukiwanie repozytorium i indeksowanie jego danych. Musisz wdrożyć strategię przechodzenia opartą na rozmiarze i układzie danych w repozytorium. Możesz zaprojektować własną strategię lub wybrać jedną z tych strategii zaimplementowanych w pakiecie SDK:

Strategia pełnego przeszukiwania

Strategia pełnego przeszukiwania skanuje całe repozytorium i indeksuje wszystkie elementy. Ta strategia jest zwykle stosowana, gdy masz małe repozytorium i możesz sobie pozwolić na pełne przeszukiwanie przy każdej indeksacji.

Ta strategia przechodzenia jest odpowiednia w przypadku małych repozytoriów zawierających głównie statyczne, niehierarchiczne dane. Możesz też użyć tej strategii przechodzenia, gdy wykrywanie zmian jest trudne lub nie jest obsługiwane przez repozytorium.

Strategia przechodzenia listy

Strategia przechodzenia po liście skanuje całe repozytorium, w tym wszystkie węzły podrzędne, i określa stan każdego elementu. Następnie oprogramowanie sprzęgające wykonuje drugie przejście i indeksuje tylko elementy, które są nowe lub zostały zaktualizowane od czasu ostatniego indeksowania. Ta strategia jest często używana do przeprowadzania przyrostowych aktualizacji istniejącego indeksu (zamiast pełnego przeszukiwania za każdym razem, gdy aktualizujesz indeks).

Ta strategia przechodzenia jest odpowiednia, gdy wykrywanie zmian jest trudne lub nie jest obsługiwane przez repozytorium, masz dane niehierarchiczne i pracujesz z bardzo dużymi zbiorami danych.

Przeszukiwanie grafu

Strategia przechodzenia po grafie skanuje cały węzeł nadrzędny, aby określić stan każdego elementu. Następnie oprogramowanie sprzęgające wykonuje drugie przejście i indeksuje tylko elementy w węźle głównym, które są nowe lub zostały zaktualizowane od czasu ostatniego indeksowania. Na koniec łącznik przekazuje identyfikatory podrzędne, a następnie indeksuje elementy w węzłach podrzędnych, które są nowe lub zostały zaktualizowane. Oprogramowanie sprzęgające kontynuuje rekursywnie przetwarzanie wszystkich węzłów podrzędnych, dopóki nie zostaną uwzględnione wszystkie elementy. Takie przechodzenie jest zwykle używane w przypadku repozytoriów hierarchicznych, w których wyświetlanie wszystkich identyfikatorów nie jest praktyczne.

Ta strategia jest odpowiednia, jeśli masz dane hierarchiczne, które wymagają indeksowania, np. serię katalogów lub stron internetowych.

Każda z tych strategii przechodzenia jest implementowana przez klasę łącznika szablonu w pakiecie SDK. Możesz wdrożyć własną strategię przechodzenia, ale te szablony znacznie przyspieszają tworzenie łącznika. Aby utworzyć łącznik za pomocą szablonu, przejdź do sekcji odpowiadającej strategii przechodzenia:

Tworzenie łącznika pełnego przeszukiwania za pomocą klasy szablonu

Ta sekcja dokumentacji odnosi się do fragmentów kodu z przykładu FullTraversalSample.

Wdrażanie punktu wejścia oprogramowania sprzęgającego

Punktem wejścia do łącznika jest metoda main(). Głównym zadaniem tej metody jest utworzenie instancji klasy Application i wywołanie jej metody start() w celu uruchomienia oprogramowania sprzęgającego.

Przed wywołaniem funkcji application.start() użyj klasy IndexingApplication.Builder do utworzenia instancji szablonu FullTraversalConnector. Funkcja FullTraversalConnector przyjmuje obiekt Repository, którego metody implementujesz. Poniższy fragment kodu pokazuje, jak zaimplementować metodę 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();
}

W tle pakiet SDK wywołuje metodę initConfig() po wywołaniu przez metodę main() łącznika metody Application.build. Metoda initConfig() wykonuje te zadania:

  1. Wywołuje metodę Configuation.isInitialized(), aby upewnić się, że zmienna Configuration nie została zainicjowana.
  2. Inicjuje obiekt Configuration za pomocą par klucz-wartość dostarczonych przez Google. Każda para klucz-wartość jest przechowywana w obiekcie ConfigValue w obiekcie Configuration.

Zaimplementuj interfejs Repository.

Jedynym celem obiektu Repository jest przechodzenie i indeksowanie elementów repozytorium. Jeśli używasz szablonu, wystarczy zastąpić niektóre metody w Repositoryinterfejsie, aby utworzyć łącznik treści. Metody, które zastępujesz, zależą od używanego szablonu i strategii przechodzenia. W przypadku FullTraversalConnector zastąp te metody:

  • Metoda init(). Aby przeprowadzić konfigurację i inicjalizację repozytorium danych, zastąp metodę init().

  • Metoda getAllDocs(). Aby przejść i zindeksować wszystkie elementy w repozytorium danych, zastąp metodę getAllDocs(). Ta metoda jest wywoływana raz dla każdego zaplanowanego przejścia (zgodnie z konfiguracją).

  • (opcjonalnie) Metoda getChanges(). Jeśli repozytorium obsługuje wykrywanie zmian, zastąp metodę getChanges(). Ta metoda jest wywoływana raz dla każdego zaplanowanego przyrostowego przejścia (zgodnie z konfiguracją), aby pobrać zmodyfikowane elementy i je zaindeksować.

  • (opcjonalnie) Metoda close(). Jeśli musisz wyczyścić repozytorium, zastąp metodę close(). Ta metoda jest wywoływana raz podczas zamykania oprogramowania sprzęgającego.

Każda z metod obiektu Repository zwraca obiekt typu ApiOperation. ApiOperation wykonuje działanie w postaci pojedynczego lub wielu wywołań IndexingService.indexItem() w celu przeprowadzenia indeksowania repozytorium.

Pobieranie parametrów konfiguracji niestandardowej

W ramach obsługi konfiguracji konektora musisz pobrać wszystkie parametry niestandardowe z obiektu Configuration. To zadanie jest zwykle wykonywane w metodzie init() Repositoryklasy.

Klasa Configuration ma kilka metod pobierania z konfiguracji różnych typów danych. Każda metoda zwraca obiekt ConfigValue. Następnie użyj metody get() obiektu ConfigValue, aby pobrać rzeczywistą wartość. Ten fragment kodu z FullTraversalSample pokazuje, jak pobrać pojedynczą niestandardową wartość całkowitą z obiektu Configuration:

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

Aby pobrać i przeanalizować parametr zawierający kilka wartości, użyj jednego z parserów typów klasy Configuration, aby podzielić dane na odrębne części. Poniższy fragment kodu z konektora samouczka używa metody getMultiValue do pobrania listy nazw repozytoriów GitHub:

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

Przeprowadź pełne przeszukiwanie

Zastąpienie getAllDocs() umożliwia pełne przeszukiwanie i indeksowanie repozytorium. Metoda getAllDocs() akceptuje punkt kontrolny. Punkt kontrolny służy do wznawiania indeksowania od określonego elementu w przypadku przerwania procesu. W przypadku każdego elementu w repozytorium wykonaj te czynności w getAllDocs()metodzie:

  1. Ustaw uprawnienia.
  2. Ustaw metadane indeksowanego elementu.
  3. Połącz metadane i element w jeden indeksowanyRepositoryDoc.
  4. Zapakuj każdy element indeksowany w iterator zwrócony przez metodę getAllDocs(). Pamiętaj, że getAllDocs() zwraca w rzeczywistości CheckpointCloseableIterable, czyli iterację obiektów ApiOperation, z których każdy reprezentuje żądanie interfejsu API wykonane na RepositoryDoc, np. indeksowanie.

Jeśli zestaw elementów jest zbyt duży, aby można go było przetworzyć w ramach jednego wywołania, uwzględnij punkt kontrolny i ustaw wartość hasMore(true), aby wskazać, że do zindeksowania jest więcej elementów.

Ustawianie uprawnień do elementu

Twoje repozytorium używa listy kontroli dostępu (ACL), aby identyfikować użytkowników lub grupy, które mają dostęp do elementu. Lista ACL to lista identyfikatorów grup lub użytkowników, którzy mają dostęp do elementu.

Musisz skopiować listę ACL używaną przez repozytorium, aby mieć pewność, że tylko użytkownicy z dostępem do elementu będą mogli zobaczyć go w wynikach wyszukiwania. Podczas indeksowania elementu należy uwzględnić listę ACL, aby Google Cloud Search miał informacje potrzebne do zapewnienia odpowiedniego poziomu dostępu do elementu.

Pakiet SDK łącznika treści udostępnia bogaty zestaw klas i metod list ACL, które umożliwiają modelowanie list ACL większości repozytoriów. Podczas indeksowania elementu musisz przeanalizować listę ACL każdego elementu w repozytorium i utworzyć odpowiednią listę ACL dla Google Cloud Search. Jeśli lista kontroli dostępu w repozytorium wykorzystuje koncepcje takie jak dziedziczenie listy kontroli dostępu, modelowanie tej listy może być trudne. Więcej informacji o listach ACL w Google Cloud Search znajdziesz w artykule Listy ACL w Google Cloud Search.

Uwaga: interfejs Cloud Search Indexing API obsługuje listy ACL w jednej domenie. Nie obsługuje list ACL w wielu domenach. Użyj klasy Acl.Builder , aby ustawić dostęp do każdego elementu za pomocą listy ACL. Poniższy fragment kodu pochodzący z pełnego przykładu przechodzenia umożliwia wszystkim użytkownikom lub „podmiotom” (getCustomerPrincipal()) bycie „czytelnikami” wszystkich elementów (.setReaders()) podczas wyszukiwania.

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

Aby prawidłowo modelować listy kontroli dostępu dla repozytorium, musisz je rozumieć. Na przykład możesz indeksować pliki w systemie plików, który korzysta z modelu dziedziczenia, w którym foldery podrzędne dziedziczą uprawnienia z folderów nadrzędnych. Modelowanie dziedziczenia list ACL wymaga dodatkowych informacji, które znajdziesz w artykule Listy ACL w Google Cloud Search.

Ustawianie metadanych elementu

Metadane są przechowywane w obiekcie Item. Aby utworzyć Item, musisz mieć co najmniej unikalny identyfikator ciągu znaków, typ elementu, listę ACL, adres URL i wersję elementu. Ten fragment kodu pokazuje, jak utworzyć obiekt Item za pomocą klasy pomocniczej 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();

Tworzenie elementu, który można indeksować

Po ustawieniu metadanych elementu możesz utworzyć rzeczywisty element indeksowany za pomocą klasy RepositoryDoc.Builder. Poniższy przykład pokazuje, jak utworzyć pojedynczy element indeksowany.

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

RepositoryDoc to rodzaj ApiOperation, który wykonuje rzeczywiste żądanie IndexingService.indexItem().

Możesz też użyć metody setRequestMode() klasy RepositoryDoc.Builder, aby określić, czy żądanie indeksowania ma być typu ASYNCHRONOUS czy SYNCHRONOUS:

ASYNCHRONOUS
Tryb asynchroniczny powoduje dłuższe opóźnienie między indeksowaniem a wyświetlaniem i umożliwia wykorzystanie dużego limitu przepustowości w przypadku żądań indeksowania. Tryb asynchroniczny jest zalecany w przypadku początkowego indeksowania (wypełniania) całego repozytorium.
SYNCHRONOUS
Tryb synchroniczny zapewnia krótsze opóźnienie od indeksowania do wyświetlania i umożliwia wykorzystanie ograniczonego limitu przepustowości. Tryb synchroniczny jest zalecany do indeksowania aktualizacji i zmian w repozytorium. Jeśli nie określisz tego parametru, domyślnie zostanie użyty tryb żądania SYNCHRONOUS.

Zapakuj każdy indeksowany element w iterator.

Metoda getAllDocs() zwraca obiekt Iterator, a konkretnie obiekt CheckpointCloseableIterable zawierający obiekty RepositoryDoc. Możesz użyć klasy CheckpointClosableIterableImpl.Builder do utworzenia i zwrócenia iteratora. Poniższy fragment kodu pokazuje, jak utworzyć i zwrócić iterator.

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

Pakiet SDK wykonuje każde wywołanie indeksowania zawarte w iteratorze.

Następne kroki

Oto kilka kolejnych kroków, które możesz podjąć:

Tworzenie łącznika przechodzenia po liście za pomocą klasy szablonu

Kolejka indeksowania Cloud Search służy do przechowywania identyfikatorów i opcjonalnych wartości skrótu dla każdego elementu w repozytorium. Łącznik przechodzący po liście przesyła identyfikatory elementów do kolejki indeksowania Google Cloud Search i pobiera je pojedynczo na potrzeby indeksowania. Google Cloud Search utrzymuje kolejki i porównuje ich zawartość, aby określić stan elementu, np. czy został on usunięty z repozytorium. Więcej informacji o kolejce indeksowania Cloud Search znajdziesz w artykule Kolejka indeksowania Cloud Search.

Ta sekcja dokumentacji odnosi się do fragmentów kodu z przykładu ListTraversalSample.

Wdrażanie punktu wejścia oprogramowania sprzęgającego

Punktem wejścia do łącznika jest metoda main(). Głównym zadaniem tej metody jest utworzenie instancji klasy Application i wywołanie jej metody start() w celu uruchomienia oprogramowania sprzęgającego.

Przed wywołaniem funkcji application.start() użyj klasy IndexingApplication.Builder do utworzenia instancji szablonu ListingConnector. Funkcja ListingConnector przyjmuje obiekt Repository, którego metody implementujesz. Poniższy fragment kodu pokazuje, jak utworzyć instancję klasy ListingConnector i powiązanej z nią klasy 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();
}

W tle pakiet SDK wywołuje metodę initConfig() po wywołaniu przez metodę main() łącznika metody Application.build. Metoda initConfig():

  1. Wywołuje metodę Configuation.isInitialized(), aby upewnić się, że zmienna Configuration nie została zainicjowana.
  2. Inicjuje obiekt Configuration za pomocą par klucz-wartość dostarczonych przez Google. Każda para klucz-wartość jest przechowywana w obiekcie ConfigValue w obiekcie Configuration.

Zaimplementuj interfejs Repository.

Jedynym celem obiektu Repository jest przechodzenie i indeksowanie elementów repozytorium. Jeśli używasz szablonu, wystarczy zastąpić niektóre metody w interfejsieRepository, aby utworzyć łącznik treści. Metody, które zastępujesz, zależą od używanego szablonu i strategii przechodzenia. W przypadku ListingConnector zastąp te metody:

  • Metoda init(). Aby przeprowadzić konfigurację i inicjalizację repozytorium danych, zastąp metodę init().

  • Metoda getIds(). Aby pobrać identyfikatory i wartości skrótu wszystkich rekordów w repozytorium, zastąp metodę getIds().

  • Metoda getDoc(). Aby dodać nowe elementy do indeksu, zaktualizować, zmodyfikować lub usunąć z niego elementy, zastąp metodę getDoc().

  • (opcjonalnie) Metoda getChanges(). Jeśli repozytorium obsługuje wykrywanie zmian, zastąp metodę getChanges(). Ta metoda jest wywoływana raz dla każdego zaplanowanego przyrostowego przejścia (zgodnie z konfiguracją), aby pobrać zmodyfikowane elementy i je zaindeksować.

  • (opcjonalnie) Metoda close(). Jeśli musisz wyczyścić repozytorium, zastąp metodę close(). Ta metoda jest wywoływana raz podczas zamykania oprogramowania sprzęgającego.

Każda z metod obiektu Repository zwraca obiekt typu ApiOperation. ApiOperation wykonuje działanie w postaci pojedynczego lub wielu wywołań IndexingService.indexItem() w celu przeprowadzenia indeksowania repozytorium.

Pobieranie parametrów konfiguracji niestandardowej

W ramach obsługi konfiguracji konektora musisz pobrać wszystkie parametry niestandardowe z obiektu Configuration. To zadanie jest zwykle wykonywane w metodzie init() Repositoryklasy.

Klasa Configuration ma kilka metod pobierania z konfiguracji różnych typów danych. Każda metoda zwraca obiekt ConfigValue. Następnie użyj metody get() obiektu ConfigValue, aby pobrać rzeczywistą wartość. Ten fragment kodu z FullTraversalSample pokazuje, jak pobrać pojedynczą niestandardową wartość całkowitą z obiektu Configuration:

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

Aby pobrać i przeanalizować parametr zawierający kilka wartości, użyj jednego z parserów typów klasy Configuration, aby podzielić dane na odrębne części. Poniższy fragment kodu z konektora samouczka używa metody getMultiValue do pobrania listy nazw repozytoriów GitHub:

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

Przejdź przez listę

Zastąp metodę getIds() pobierania identyfikatorów i wartości skrótu wszystkich rekordów w repozytorium. Metoda getIds() akceptuje punkt kontrolny. Punkt kontrolny służy do wznawiania indeksowania od określonego elementu w przypadku przerwania procesu.

Następnie zastąp metodę getDoc() tak, aby obsługiwała każdy element w kolejce indeksowania Cloud Search.

Przesyłanie identyfikatorów produktów i wartości skrótu

Zastąp getIds() aby pobrać identyfikatory produktów i powiązane z nimi wartości skrótu treści z repozytorium. Pary identyfikatorów i wartości skrótu są następnie pakowane w operację push i wysyłane do kolejki indeksowania Cloud Search. Identyfikatory główne lub nadrzędne są zwykle przesyłane jako pierwsze, a potem identyfikatory podrzędne, aż cała hierarchia produktów zostanie przetworzona.

Metoda getIds() akceptuje punkt kontrolny reprezentujący ostatni element do zindeksowania. Punkt kontrolny może służyć do wznowienia indeksowania od określonego elementu w przypadku przerwania procesu. W przypadku każdego elementu w repozytorium wykonaj te czynności w metodzie getIds():

  • Pobierz z repozytorium identyfikator każdego produktu i powiązaną z nim wartość skrótu.
  • Każdą parę identyfikator i wartość skrótu umieść w elemencie PushItems.
  • Połącz każdy element PushItems w iterator zwrócony przez metodę getIds(). Pamiętaj, że getIds() zwraca w rzeczywistości CheckpointCloseableIterable, czyli iterację obiektów ApiOperation, z których każdy reprezentuje żądanie interfejsu API wykonane na RepositoryDoc, np. przesłanie elementów do kolejki.

Poniższy fragment kodu pokazuje, jak pobrać identyfikator i wartość skrótu każdego produktu oraz wstawić je do elementu PushItems. PushItems to ApiOperation żądanie przesłania elementu do kolejki indeksowania 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);
}

Poniższy fragment kodu pokazuje, jak używać klasy PushItems.Builder do pakowania identyfikatorów i wartości skrótu w pojedynczym działaniu push ApiOperation.

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

Elementy są przesyłane do kolejki indeksowania Cloud Search w celu dalszego przetwarzania.

Pobieranie i obsługa każdego elementu

Zastąp getDoc(), aby obsługiwać każdy element w kolejce indeksowania Cloud Search. Element może być nowy, zmodyfikowany, niezmieniony lub może już nie istnieć w repozytorium źródłowym. Pobierz i zindeksuj każdy nowy lub zmodyfikowany element. Usuń z indeksu elementy, które nie istnieją już w repozytorium źródłowym.

Metoda getDoc() akceptuje element z kolejki indeksowania Google Cloud Search. W przypadku każdego elementu w kolejce wykonaj te czynności w metodzie getDoc():

  1. Sprawdź, czy identyfikator elementu w kolejce indeksowania Cloud Search istnieje w repozytorium. Jeśli nie, usuń go z indeksu.

  2. Sprawdź stan elementu w indeksie. Jeśli element nie uległ zmianie (ACCEPTED), nie rób nic.

  3. Zmiana indeksu lub nowe elementy:

    1. Ustaw uprawnienia.
    2. Ustaw metadane indeksowanego elementu.
    3. Połącz metadane i element w jeden indeksowanyRepositoryDoc.
    4. Zwróć RepositoryDoc.

Uwaga: szablon ListingConnector nie obsługuje zwracania null w metodzie getDoc(). Zwrócenie null powoduje NullPointerException.

Obsługa usuniętych elementów

Ten fragment kodu pokazuje, jak sprawdzić, czy element istnieje w repozytorium, a jeśli nie, usunąć go.

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

Pamiętaj, że documents to struktura danych reprezentująca repozytorium. Jeśli w documents nie znaleziono documentID, zwróć APIOperations.deleteItem(resourceName), aby usunąć element z indeksu.

Obsługa niezmienionych elementów

Ten fragment kodu pokazuje, jak sprawdzać stan elementu w kolejce indeksowania Cloud Search i obsługiwać niezmieniony element.

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

Aby sprawdzić, czy element nie został zmodyfikowany, sprawdź jego stan oraz inne metadane, które mogą wskazywać na zmianę. W tym przykładzie do określenia, czy element został zmieniony, używany jest skrót metadanych.

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

Ustawianie uprawnień do elementu

Twoje repozytorium używa listy kontroli dostępu (ACL), aby identyfikować użytkowników lub grupy, które mają dostęp do elementu. Lista ACL to lista identyfikatorów grup lub użytkowników, którzy mają dostęp do elementu.

Musisz skopiować listę ACL używaną przez repozytorium, aby mieć pewność, że tylko użytkownicy z dostępem do elementu będą mogli zobaczyć go w wynikach wyszukiwania. Podczas indeksowania elementu należy uwzględnić listę ACL, aby Google Cloud Search miał informacje potrzebne do zapewnienia odpowiedniego poziomu dostępu do elementu.

Pakiet SDK łącznika treści udostępnia bogaty zestaw klas i metod list ACL, które umożliwiają modelowanie list ACL większości repozytoriów. Podczas indeksowania elementu musisz przeanalizować listę ACL każdego elementu w repozytorium i utworzyć odpowiednią listę ACL dla Google Cloud Search. Jeśli lista kontroli dostępu w repozytorium wykorzystuje koncepcje takie jak dziedziczenie listy kontroli dostępu, modelowanie tej listy może być trudne. Więcej informacji o listach ACL w Google Cloud Search znajdziesz w artykule Listy ACL w Google Cloud Search.

Uwaga: interfejs Cloud Search Indexing API obsługuje listy ACL w jednej domenie. Nie obsługuje list ACL w wielu domenach. Użyj klasy Acl.Builder , aby ustawić dostęp do każdego elementu za pomocą listy ACL. Poniższy fragment kodu pochodzący z pełnego przykładu przechodzenia umożliwia wszystkim użytkownikom lub „podmiotom” (getCustomerPrincipal()) bycie „czytelnikami” wszystkich elementów (.setReaders()) podczas wyszukiwania.

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

Aby prawidłowo modelować listy kontroli dostępu dla repozytorium, musisz je rozumieć. Na przykład możesz indeksować pliki w systemie plików, który korzysta z modelu dziedziczenia, w którym foldery podrzędne dziedziczą uprawnienia z folderów nadrzędnych. Modelowanie dziedziczenia list ACL wymaga dodatkowych informacji, które znajdziesz w artykule Listy ACL w Google Cloud Search.

Ustawianie metadanych elementu

Metadane są przechowywane w obiekcie Item. Aby utworzyć Item, musisz mieć co najmniej unikalny identyfikator ciągu znaków, typ elementu, listę ACL, adres URL i wersję elementu. Ten fragment kodu pokazuje, jak utworzyć obiekt Item za pomocą klasy pomocniczej 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();

Tworzenie elementu, który można indeksować

Po ustawieniu metadanych elementu możesz utworzyć indeksowany element za pomocą elementu RepositoryDoc.Builder. Poniższy przykład pokazuje, jak utworzyć pojedynczy element indeksowany.

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

RepositoryDoc to rodzaj ApiOperation, który wykonuje rzeczywiste żądanie IndexingService.indexItem().

Możesz też użyć metody setRequestMode() klasy RepositoryDoc.Builder, aby określić, czy żądanie indeksowania ma być typu ASYNCHRONOUS czy SYNCHRONOUS:

ASYNCHRONOUS
Tryb asynchroniczny powoduje dłuższe opóźnienie między indeksowaniem a wyświetlaniem i umożliwia wykorzystanie dużego limitu przepustowości w przypadku żądań indeksowania. Tryb asynchroniczny jest zalecany w przypadku początkowego indeksowania (wypełniania) całego repozytorium.
SYNCHRONOUS
Tryb synchroniczny zapewnia krótsze opóźnienie od indeksowania do wyświetlania i umożliwia wykorzystanie ograniczonego limitu przepustowości. Tryb synchroniczny jest zalecany do indeksowania aktualizacji i zmian w repozytorium. Jeśli nie określisz tego parametru, domyślnie zostanie użyty tryb żądania SYNCHRONOUS.

Następne kroki

Oto kilka kolejnych kroków, które możesz podjąć:

Tworzenie łącznika przechodzenia po grafie za pomocą klasy szablonu

Kolejka indeksowania Cloud Search służy do przechowywania identyfikatorów i opcjonalnych wartości skrótu każdego elementu w repozytorium. Łącznik przechodzenia po grafie przesyła identyfikatory elementów do kolejki indeksowania Google Cloud Search i pobiera je pojedynczo na potrzeby indeksowania. Cloud Search utrzymuje kolejki i porównuje ich zawartość, aby określić stan elementu, np. czy został on usunięty z repozytorium. Więcej informacji o kolejce indeksowania Cloud Search znajdziesz w artykule Kolejka indeksowania Google Cloud Search.

Podczas indeksowania zawartość elementu jest pobierana z repozytorium danych, a identyfikatory elementów podrzędnych są umieszczane w kolejce. Łącznik przetwarza rekurencyjnie identyfikatory elementów nadrzędnych i podrzędnych, dopóki nie zostaną obsłużone wszystkie elementy.

Ta sekcja dokumentacji odnosi się do fragmentów kodu z przykładu GraphTraversalSample.

Wdrażanie punktu wejścia oprogramowania sprzęgającego

Punktem wejścia do łącznika jest metoda main(). Głównym zadaniem tej metody jest utworzenie instancji klasy Application i wywołanie jej metody start() w celu uruchomienia oprogramowania sprzęgającego.

Przed wywołaniem funkcji application.start() użyj klasy IndexingApplication.Builder do utworzenia instancji szablonu ListingConnector. Funkcja ListingConnector przyjmuje obiekt Repository, którego metody implementujesz.

Poniższy fragment kodu pokazuje, jak utworzyć instancję klasy ListingConnector i powiązanej z nią klasy 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();
}

W tle pakiet SDK wywołuje metodę initConfig() po wywołaniu przez metodę main() łącznika metody Application.build. Metoda initConfig():

  1. Wywołuje metodę Configuation.isInitialized(), aby upewnić się, że zmienna Configuration nie została zainicjowana.
  2. Inicjuje obiekt Configuration za pomocą par klucz-wartość dostarczonych przez Google. Każda para klucz-wartość jest przechowywana w obiekcie ConfigValue w obiekcie Configuration.

Zaimplementuj interfejs Repository.

Jedynym celem obiektu Repository jest przechodzenie i indeksowanie elementów repozytorium. Jeśli używasz szablonu, wystarczy zastąpić niektóre metody w interfejsie Repository, aby utworzyć łącznik treści. Metody, które zastępujesz, zależą od używanego szablonu i strategii przechodzenia. W przypadku ListingConnector zastępujesz te metody:

  • Metoda init(). Aby przeprowadzić konfigurację i inicjalizację repozytorium danych, zastąp metodę init().

  • Metoda getIds(). Aby pobrać identyfikatory i wartości skrótu wszystkich rekordów w repozytorium, zastąp metodę getIds().

  • Metoda getDoc(). Aby dodać nowe elementy do indeksu, zaktualizować, zmodyfikować lub usunąć z niego elementy, zastąp metodę getDoc().

  • (opcjonalnie) Metoda getChanges(). Jeśli repozytorium obsługuje wykrywanie zmian, zastąp metodę getChanges(). Ta metoda jest wywoływana raz dla każdego zaplanowanego przyrostowego przejścia (zgodnie z konfiguracją), aby pobrać zmodyfikowane elementy i je zaindeksować.

  • (opcjonalnie) Metoda close(). Jeśli musisz wyczyścić repozytorium, zastąp metodę close(). Ta metoda jest wywoływana raz podczas zamykania oprogramowania sprzęgającego.

Każda z metod obiektu Repository zwraca obiekt typu ApiOperation. ApiOperationObiekt wykonuje działanie w postaci pojedynczego lub wielokrotnego wywołania IndexingService.indexItem() w celu przeprowadzenia indeksowania repozytorium.

Pobieranie parametrów konfiguracji niestandardowej

W ramach obsługi konfiguracji konektora musisz pobrać wszystkie parametry niestandardowe z obiektu Configuration. To zadanie jest zwykle wykonywane w metodzie init() Repositoryklasy.

Klasa Configuration ma kilka metod pobierania z konfiguracji różnych typów danych. Każda metoda zwraca obiekt ConfigValue. Następnie użyj metody get() obiektu ConfigValue, aby pobrać rzeczywistą wartość. Ten fragment kodu z FullTraversalSample pokazuje, jak pobrać pojedynczą niestandardową wartość całkowitą z obiektu Configuration:

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

Aby pobrać i przeanalizować parametr zawierający kilka wartości, użyj jednego z parserów typów klasy Configuration, aby podzielić dane na odrębne części. Poniższy fragment kodu z konektora samouczka używa metody getMultiValue do pobrania listy nazw repozytoriów GitHub:

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

Wykonaj przeszukiwanie grafu

Zastąp metodę getIds() pobierania identyfikatorów i wartości skrótu wszystkich rekordów w repozytorium. Metoda getIds() akceptuje punkt kontrolny. Punkt kontrolny służy do wznawiania indeksowania od określonego elementu w przypadku przerwania procesu.

Następnie zastąp metodę getDoc() tak, aby obsługiwała każdy element w kolejce indeksowania Cloud Search.

Przesyłanie identyfikatorów produktów i wartości skrótu

Zastąp getIds() aby pobrać identyfikatory produktów i powiązane z nimi wartości skrótu treści z repozytorium. Pary identyfikatorów i wartości skrótu są następnie pakowane w operację push i wysyłane do kolejki indeksowania Cloud Search. Identyfikatory główne lub nadrzędne są zwykle przesyłane jako pierwsze, a potem identyfikatory podrzędne, aż cała hierarchia produktów zostanie przetworzona.

Metoda getIds() akceptuje punkt kontrolny reprezentujący ostatni element do zindeksowania. Punkt kontrolny może służyć do wznowienia indeksowania od określonego elementu w przypadku przerwania procesu. W przypadku każdego elementu w repozytorium wykonaj te czynności w metodzie getIds():

  • Pobierz z repozytorium identyfikator każdego produktu i powiązaną z nim wartość skrótu.
  • Każdą parę identyfikator i wartość skrótu umieść w elemencie PushItems.
  • Połącz każdy element PushItems w iterator zwrócony przez metodę getIds(). Pamiętaj, że getIds() zwraca w rzeczywistości CheckpointCloseableIterable, czyli iterację obiektów ApiOperation, z których każdy reprezentuje żądanie interfejsu API wykonane na RepositoryDoc, np. przesłanie elementów do kolejki.

Poniższy fragment kodu pokazuje, jak pobrać identyfikator i wartość skrótu każdego elementu i wstawić je do PushItems. PushItems to żądanieApiOperation przesłania elementu do kolejki indeksowania Cloud Search.

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

Poniższy fragment kodu pokazuje, jak za pomocą klasy PushItems.Builder spakować identyfikatory i wartości skrótu w jedno działanie push ApiOperation.

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

Elementy są przesyłane do kolejki indeksowania Cloud Search w celu dalszego przetwarzania.

Pobieranie i obsługa każdego elementu

Zastąp getDoc(), aby obsługiwać każdy element w kolejce indeksowania Cloud Search. Element może być nowy, zmodyfikowany, niezmieniony lub może już nie istnieć w repozytorium źródłowym. Pobierz i zindeksuj każdy nowy lub zmodyfikowany element. Usuń z indeksu elementy, które nie istnieją już w repozytorium źródłowym.

Metoda getDoc() akceptuje element z kolejki indeksowania Cloud Search. W przypadku każdego elementu w kolejce wykonaj te czynności w metodzie getDoc():

  1. Sprawdź, czy identyfikator elementu w kolejce indeksowania Cloud Search istnieje w repozytorium. Jeśli nie, usuń go z indeksu. Jeśli produkt istnieje, przejdź do następnego kroku.

  2. Zmiana indeksu lub nowe elementy:

    1. Ustaw uprawnienia.
    2. Ustaw metadane indeksowanego elementu.
    3. Połącz metadane i element w jeden indeksowanyRepositoryDoc.
    4. Umieść identyfikatory elementów podrzędnych w kolejce indeksowania Cloud Search w celu dalszego przetwarzania.
    5. Zwróć RepositoryDoc.

Obsługa usuniętych elementów

Poniższy fragment kodu pokazuje, jak sprawdzić, czy element istnieje w indeksie, a jeśli nie, usunąć go.

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

Ustawianie uprawnień do elementu

Twoje repozytorium używa listy kontroli dostępu (ACL), aby identyfikować użytkowników lub grupy, które mają dostęp do elementu. Lista ACL to lista identyfikatorów grup lub użytkowników, którzy mają dostęp do elementu.

Musisz skopiować listę ACL używaną przez repozytorium, aby mieć pewność, że tylko użytkownicy z dostępem do elementu będą mogli zobaczyć go w wynikach wyszukiwania. Podczas indeksowania elementu należy uwzględnić listę ACL, aby Google Cloud Search miał informacje potrzebne do zapewnienia odpowiedniego poziomu dostępu do elementu.

Pakiet SDK łącznika treści udostępnia bogaty zestaw klas i metod list ACL, które umożliwiają modelowanie list ACL większości repozytoriów. Podczas indeksowania elementu musisz przeanalizować listę ACL każdego elementu w repozytorium i utworzyć odpowiednią listę ACL dla Google Cloud Search. Jeśli lista kontroli dostępu w repozytorium wykorzystuje koncepcje takie jak dziedziczenie listy kontroli dostępu, modelowanie tej listy może być trudne. Więcej informacji o listach ACL w Google Cloud Search znajdziesz w artykule Listy ACL w Google Cloud Search.

Uwaga: interfejs Cloud Search Indexing API obsługuje listy ACL w jednej domenie. Nie obsługuje list ACL w wielu domenach. Użyj klasy Acl.Builder , aby ustawić dostęp do każdego elementu za pomocą listy ACL. Poniższy fragment kodu pochodzący z pełnego przykładu przechodzenia umożliwia wszystkim użytkownikom lub „podmiotom” (getCustomerPrincipal()) bycie „czytelnikami” wszystkich elementów (.setReaders()) podczas wyszukiwania.

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

Aby prawidłowo modelować listy kontroli dostępu dla repozytorium, musisz je rozumieć. Na przykład możesz indeksować pliki w systemie plików, który korzysta z modelu dziedziczenia, w którym foldery podrzędne dziedziczą uprawnienia z folderów nadrzędnych. Modelowanie dziedziczenia list ACL wymaga dodatkowych informacji, które znajdziesz w artykule Listy ACL w Google Cloud Search.

Ustawianie metadanych elementu

Metadane są przechowywane w obiekcie Item. Aby utworzyć Item, musisz mieć co najmniej unikalny identyfikator ciągu znaków, typ elementu, listę ACL, adres URL i wersję elementu. Ten fragment kodu pokazuje, jak utworzyć obiekt Item za pomocą klasy pomocniczej 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();

Tworzenie elementu, który można indeksować

Po ustawieniu metadanych elementu możesz utworzyć indeksowany element za pomocą elementu RepositoryDoc.Builder. Poniższy przykład pokazuje, jak utworzyć pojedynczy element indeksowany.

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

RepositoryDoc to rodzaj ApiOperation, który wykonuje rzeczywiste żądanie IndexingService.indexItem().

Możesz też użyć metody setRequestMode() klasy RepositoryDoc.Builder, aby określić, czy żądanie indeksowania ma być typu ASYNCHRONOUS czy SYNCHRONOUS:

ASYNCHRONOUS
Tryb asynchroniczny powoduje dłuższe opóźnienie między indeksowaniem a wyświetlaniem i umożliwia wykorzystanie dużego limitu przepustowości w przypadku żądań indeksowania. Tryb asynchroniczny jest zalecany w przypadku początkowego indeksowania (wypełniania) całego repozytorium.
SYNCHRONOUS
Tryb synchroniczny zapewnia krótsze opóźnienie od indeksowania do wyświetlania i umożliwia wykorzystanie ograniczonego limitu przepustowości. Tryb synchroniczny jest zalecany do indeksowania aktualizacji i zmian w repozytorium. Jeśli nie określisz tego parametru, domyślnie zostanie użyty tryb żądania SYNCHRONOUS.

Umieszczanie identyfikatorów elementów podrzędnych w kolejce indeksowania Cloud Search

Ten fragment kodu pokazuje, jak uwzględnić identyfikatory elementów podrzędnych aktualnie przetwarzanego elementu nadrzędnego w kolejce do przetworzenia. Te identyfikatory są przetwarzane po zindeksowaniu elementu nadrzędnego.

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

Następne kroki

Oto kilka kolejnych kroków, które możesz podjąć:

Tworzenie oprogramowania sprzęgającego treści przy użyciu interfejsu API REST

W sekcjach poniżej dowiesz się, jak utworzyć oprogramowanie sprzęgające treści za pomocą interfejsu API typu REST.

Określ strategię przechodzenia

Główną funkcją łącznika treści jest przeszukiwanie repozytorium i indeksowanie jego danych. Musisz wdrożyć strategię przechodzenia opartą na rozmiarze i układzie danych w repozytorium. Oto 3 popularne strategie przechodzenia:

Strategia pełnego przeszukiwania

Strategia pełnego przeszukiwania skanuje całe repozytorium i indeksuje wszystkie elementy. Ta strategia jest zwykle stosowana, gdy masz małe repozytorium i możesz sobie pozwolić na pełne przeszukiwanie przy każdej indeksacji.

Ta strategia przechodzenia jest odpowiednia w przypadku małych repozytoriów zawierających głównie statyczne, niehierarchiczne dane. Możesz też użyć tej strategii przechodzenia, gdy wykrywanie zmian jest trudne lub nie jest obsługiwane przez repozytorium.

Strategia przechodzenia listy

Strategia przechodzenia po liście skanuje całe repozytorium, w tym wszystkie węzły podrzędne, i określa stan każdego elementu. Następnie oprogramowanie sprzęgające wykonuje drugie przejście i indeksuje tylko elementy, które są nowe lub zostały zaktualizowane od czasu ostatniego indeksowania. Ta strategia jest często używana do przeprowadzania przyrostowych aktualizacji istniejącego indeksu (zamiast pełnego przeszukiwania za każdym razem, gdy aktualizujesz indeks).

Ta strategia przechodzenia jest odpowiednia, gdy wykrywanie zmian jest trudne lub nie jest obsługiwane przez repozytorium, masz dane niehierarchiczne i pracujesz z bardzo dużymi zbiorami danych.

Przeszukiwanie grafu

Strategia przechodzenia po grafie skanuje cały węzeł nadrzędny, aby określić stan każdego elementu. Następnie oprogramowanie sprzęgające wykonuje drugie przejście i indeksuje tylko elementy w węźle głównym, które są nowe lub zostały zaktualizowane od czasu ostatniego indeksowania. Na koniec łącznik przekazuje identyfikatory podrzędne, a następnie indeksuje elementy w węzłach podrzędnych, które są nowe lub zostały zaktualizowane. Oprogramowanie sprzęgające kontynuuje rekursywnie przetwarzanie wszystkich węzłów podrzędnych, dopóki nie zostaną uwzględnione wszystkie elementy. Takie przechodzenie jest zwykle używane w przypadku repozytoriów hierarchicznych, w których wyświetlanie wszystkich identyfikatorów nie jest praktyczne.

Ta strategia jest odpowiednia, jeśli masz dane hierarchiczne, które wymagają indeksowania, np. serię katalogów lub stron internetowych.

Wdrażanie strategii przechodzenia i indeksowanie elementów

Każdy element indeksowany w Cloud Search jest określany w Cloud Search API jako element. Elementem może być plik, folder, wiersz w pliku CSV lub rekord bazy danych.

Po zarejestrowaniu schematu możesz wypełnić indeks, wykonując te czynności:

  1. (opcjonalnie) Użyj items.upload, aby przesłać pliki większe niż 100 KiB do indeksowania. W przypadku mniejszych plików osadź treść jako inlineContent za pomocą items.index.

  2. (opcjonalnie) Użyj media.upload, aby przesłać pliki multimedialne do indeksowania.

  3. Użyj items.index, aby zindeksować element. Jeśli na przykład Twój schemat używa definicji obiektu w schemacie filmu, żądanie indeksowania pojedynczego elementu będzie wyglądać tak:

    {
      "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. (Opcjonalnie) Użyj wywołań items.get, aby sprawdzić, czy produkt został zindeksowany.

Aby przeprowadzić pełne przeszukiwanie, należy okresowo ponownie indeksować całe repozytorium. Aby przejść listę lub wykres, musisz zaimplementować kod, który obsługuje zmiany w repozytorium.

Obsługa zmian w repozytorium

Możesz okresowo zbierać i indeksować każdy element z repozytorium, aby przeprowadzić pełne indeksowanie. Pełne indeksowanie jest skuteczne w zapewnianiu aktualności indeksu, ale może być kosztowne w przypadku większych lub hierarchicznych repozytoriów.

Zamiast używać wywołań indeksu do okresowego indeksowania całego repozytorium, możesz też użyć kolejki indeksowania Google Cloud jako mechanizmu śledzenia zmian i indeksowania tylko tych elementów, które uległy zmianie. Możesz używać żądań items.push, aby umieszczać elementy w kolejce do późniejszego odpytywania i aktualizowania. Więcej informacji o kolejce indeksowania Google Cloud znajdziesz w artykule Kolejka indeksowania Google Cloud.

Więcej informacji o interfejsie Google Cloud Search API znajdziesz w artykule Cloud Search API.