Tworzenie łącznika treści

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

Typowy łącznik treści wykonuje te zadania:

  1. Czyta i przetwarza parametry konfiguracji.
  2. Pobiera z zewnętrznego repozytorium treści poszczególne fragmenty danych, które można indeksować, zwane „elementami”.
  3. Łączy listy kontroli dostępu, metadane i dane treści w elementy indeksowane.
  4. Indeksuje elementy w źródle danych Cloud Search.
  5. (opcjonalnie) Słucha powiadomień o zmianach w repozytorium treści zewnętrznych. Powiadomienia o zmianach są przekształcane w żądania indeksowania, aby źródło danych Cloud Search było zsynchronizowane z repozytorium innej firmy. Konwerter wykonuje to zadanie tylko wtedy, gdy repozytorium obsługuje wykrywanie zmian.

Tworzenie łącznika treści za pomocą pakietu SDK Content Connector

W kolejnych sekcjach opisujemy, 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. Aby wyświetlić zależności ś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 konfiguracji zawierający parametry używane przez łącznik, takie jak identyfikator repozytorium. Parametry są definiowane jako pary klucz-wartość, np. api.sourceId=1234567890abcdef.

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

  • W przypadku łącznika treści musisz zadeklarować parametry api.sourceId i api.serviceAccountPrivateKeyFile, ponieważ wskazują one lokalizację repozytorium i klucz prywatny potrzebny do uzyskania dostępu do repozytorium.
  • W przypadku łącznika tożsamości musisz zadeklarować parametr api.identitySourceId, ponieważ wskazuje on 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.

O ile nie chcesz zastąpić domyślnych wartości innych parametrów dostarczanych przez Google, nie musisz ich deklarować w pliku konfiguracyjnym. Więcej informacji o parametrach konfiguracji udostępnianych przez Google, np. o generowaniu określonych identyfikatorów i kluczy, znajdziesz w artykule Parametry konfiguracji udostępniane przez Google.

Możesz też zdefiniować własne parametry 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. Właściwość tę możesz ustawić, używając argumentu -D podczas uruchamiania łącznika. Na przykład to polecenie uruchamia łącznik za pomocą pliku konfiguracji MyConfig.properties:

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

Jeśli ten argument jest nieobecny, pakiet SDK próbuje uzyskać dostęp do domyślnego pliku konfiguracji o nazwie connector-config.properties.

Określanie strategii przeszukiwania

Podstawową funkcją łącznika treści jest przeszukiwanie repozytorium i indeksowanie jego danych. Musisz zastosować strategię przeszukiwania na podstawie rozmiaru i układu danych w repozytorium. Możesz zaprojektować własną strategię lub wybrać jedną z tych implementowanych w pakiecie SDK:

Strategia pełnego przeszukiwania

Strategia pełnego przeszukiwania skanuje całe repozytorium i indeksuje wszystkie elementy. Ta strategia jest często stosowana, gdy masz małe repozytorium i możesz sobie pozwolić na obciążenie związane z pełnym przeszukiwaniem za każdym razem, gdy indeksujesz.

Ta strategia przeszukiwania jest odpowiednia w przypadku małych repozytoriów z głównie statycznymi, niehierarchicznymi danymi. Możesz też użyć tej strategii przeszukiwania, gdy wykrywanie zmian jest trudne lub nieobsługiwane przez repozytorium.

List traversal strategy

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

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

Przeglądanie grafu

Strategia przeszukiwania grafu skanuje cały węzeł nadrzędny, aby określić stan każdego elementu. Następnie oprogramowanie sprzęgające wykonuje drugi przejazd i indeksuje tylko te elementy w węźle głównym, które są nowe lub zostały zaktualizowane od czasu ostatniego indeksowania. Na koniec usługa przekazuje wszystkie identyfikatory elementów podrzędnych, a następnie indeksuje elementy w podrzędnych węzłach, które są nowe lub zostały zaktualizowane. Połączenie przechodzi rekurencyjnie przez wszystkie węzły podrzędne, dopóki nie zostaną przetworzone wszystkie elementy. Takie przeszukiwanie 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 hierarchicznej, które wymagają zindeksowania, np. serię katalogów lub stron internetowych.

Każda z tych strategii przeszukiwania jest implementowana przez klasę łącznika szablonów w pakiecie SDK. Możesz zastosować własną strategię przeszukiwania, ale te szablony znacznie przyspieszą rozwój Twojego łącznika. Aby utworzyć łącznik za pomocą szablonu, przejdź do sekcji odpowiadającej Twojej strategii przeszukiwania:

Tworzenie pełnego złączenia nawigacyjnego za pomocą klasy szablonu

Ta sekcja dokumentów odnosi się do fragmentów kodu z pliku FullTraversalSample.

Implementowanie punktu wejścia oprogramowania sprzęgającego

Punkt wejścia do łącznika to metoda main(). Głównym zadaniem tej metody jest utworzenie instancji klasy Application i wywołanie jej metody start(), aby uruchomić oprogramowanie sprzęgające.

Zanim wywołasz funkcję application.start(), użyj klasy IndexingApplication.Builder do utworzenia instancji szablonu FullTraversalConnector. Funkcja FullTraversalConnector przyjmuje obiekt Repository, którego metody implementujesz. Ten fragment kodu pokazuje, jak zastosować 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 metody main() w kontekście połączenia Application.build. Metoda initConfig() wykonuje te zadania:

  1. Wywołuje metodę Configuation.isInitialized(), aby sprawdzić, czy nie została zainicjowana zmienna Configuration.
  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 przeszukiwanie i indeksowanie elementów repozytorium. Aby utworzyć łącznik treści, wystarczy zastąpić określone metody w interfejsie Repository. Metody, które zastąpisz, zależą od używanego szablonu i strategii przeszukiwania. W przypadku pola FullTraversalConnector zastąpij te metody:

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

  • metoda getAllDocs(). Aby przejść przez wszystkie elementy w repozytorium danych i z nich wygenerować indeks, zastąpij 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ąpij metodę getChanges(). Ta metoda jest wywoływana raz dla każdej zaplanowanej iteracyjnej iteracji (zgodnie z konfiguracją), aby pobierać zmodyfikowane elementy i je indeksować.

  • (opcjonalnie) metoda close(). Jeśli musisz wyczyścić repozytorium, zastąpij metodę close(). Ta metoda jest wywoływana raz podczas zamykania łącznika.

Każda z metod obiektu Repository zwraca obiekt typu ApiOperation. Obiekt ApiOperation wykonuje działanie w postaci pojedynczego lub wielu wywołań funkcji IndexingService.indexItem(), aby przeprowadzić faktyczne indeksowanie repozytorium.

Pobieranie parametrów konfiguracji niestandardowej

W ramach obsługi konfiguracji łącznika musisz pobrać wszystkie parametry niestandardowe z obiektu Configuration. Zwykle jest to wykonywane w ramach metody Repository klasy init().

Klasa Configuration udostępnia kilka metod służących do uzyskiwania różnych typów danych z konfiguracji. Każda metoda zwraca obiekt ConfigValue. Następnie użyjesz metody get() obiektu ConfigValue, aby pobrać rzeczywistą wartość. Ten fragment kodu z FullTraversalSample pokazuje, jak pobrać jedną 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 analizatorów typu klasy Configuration, aby przeanalizować dane na oddzielne fragmenty. Ten fragment kodu z samouczka używa metody getMultiValue do uzyskania listy nazw repozytoriów GitHub:

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

Wykonywanie pełnego przejścia

ZastąpićgetAllDocs(), aby przeprowadzić pełne przeszukiwanie i zaindeksować repozytorium. Metoda getAllDocs() przyjmuje punkt kontrolny. Punkt kontrolny służy do wznowienia indeksowania w przypadku przerwania procesu. W przypadku każdego elementu w Twoim repozytorium wykonaj te czynności w ramach metody getAllDocs():

  1. Ustaw uprawnienia.
  2. Ustaw metadane dla indeksowanego elementu.
  3. Połącz metadane i element w jeden indeksowalny element.RepositoryDoc
  4. Zawijaj każdy indeksowalny element w iterator zwracany przez metodę getAllDocs(). Pamiętaj, że getAllDocs() zwraca obiekt CheckpointCloseableIterable, który jest iteracją obiektów ApiOperation. Każdy z nich reprezentuje żądanie interfejsu API wykonane na RepositoryDoc, np. indeksowanie.

Jeśli zbiór elementów jest zbyt duży, aby przetworzyć go w pojedynczym wywołaniu, dodaj punkt kontrolny i ustaw parametr hasMore(true), aby wskazać, że więcej elementów jest dostępnych do indeksowania.

Ustawianie uprawnień dotyczących elementu

Repozytorium używa listy kontroli dostępu (ACL) do identyfikowania użytkowników lub grup, 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 powielić reguły ACL używane przez repozytorium, aby mieć pewność, że tylko użytkownicy z dostępem do danego elementu będą mogli go zobaczyć w wynikach wyszukiwania. Podczas indeksowania elementu należy uwzględnić jego listę ACL, aby Google Cloud Search miał informacje potrzebne do zapewnienia odpowiedniego poziomu dostępu do elementu.

Pakiet SDK Content Connector udostępnia bogaty zestaw klas i metod 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 ACL repozytorium korzysta z takich pojęć jak dziedziczenie listy ACL, modelowanie tej listy może być trudne. Więcej informacji o regułach dostępu w Google Cloud Search znajdziesz w artykule Reguły dostępu w Google Cloud Search.

Uwaga: interfejs Cloud Search Indexing API obsługuje uprawnienia ACL dla jednej domeny. Nie obsługuje list ACL między domenami. Użyj klasy Acl.Builder, aby ustawić dostęp do poszczególnych elementów za pomocą listy kontroli dostępu. Poniższy fragment kodu pochodzący z pełnego przykładu przeszukiwania umożliwia wszystkim użytkownikom lub „podmiotom” (getCustomerPrincipal()) być „czytnikami” 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 w repozytorium, musisz je dobrze rozumieć. Na przykład możesz indeksować pliki w systemie plików, który używa pewnego modelu dziedziczenia, w którym foldery podrzędne dziedziczą uprawnienia z folderów nadrzędnych. Modelowanie dziedziczenia uprawnień wymaga dodatkowych informacji, które znajdziesz w artykule Uprawnienia dostępu w Google Cloud Search.

Ustawianie metadanych produktu

Metadane są przechowywane w obiekcie Item. Aby utworzyć element Item, musisz podać 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();

Utwórz element możliwy do zindeksowania

Po ustawieniu metadanych elementu możesz utworzyć rzeczywisty indeksowalny element za pomocą klasy RepositoryDoc.Builder. W tym przykładzie pokazujemy, jak utworzyć pojedynczy indeksowalny element.

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 typ ApiOperation, który wykonuje rzeczywiste żądanie IndexingService.indexItem().

Możesz też użyć metody setRequestMode() klasy RepositoryDoc.Builder, aby zidentyfikować żądanie indeksowania jako ASYNCHRONOUS lub SYNCHRONOUS:

ASYNCHRONOUS
Tryb asynchroniczny powoduje dłuższy czas od indeksowania do wyświetlania i umożliwia stosowanie dużego limitu przepustowości dla żądań indeksowania. Tryb asynchroniczny jest zalecany do początkowego indeksowania (uzupełniania) całego repozytorium.
SYNCHRONOUS
Tryb synchroniczny powoduje krótsze opóźnienie między indeksowaniem a wyświetlaniem i umożliwia korzystanie z ograniczonej puli przepustowości. Tryb synchroniczny jest zalecany do indeksowania aktualizacji i zmian w repozytorium. Jeśli nie określisz trybu żądania, zostanie użyte ustawienie domyślne SYNCHRONOUS.

Pakowanie każdego indeksowalnego elementu w iteratorze

Metoda getAllDocs() zwraca obiekt Iterator, a w szczególności CheckpointCloseableIterable obiektów RepositoryDoc. Aby utworzyć i zwrócić iterator, możesz użyć klasy CheckpointClosableIterableImpl.Builder. Ten 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 wykonać:

Tworzenie łącznika do przeszukiwania list za pomocą klasy szablonu

Kolejka indeksowania Cloud Search służy do przechowywania identyfikatorów i opcjonalnych wartości haszowanych dla każdego elementu w repozytorium. Łącznik przeszukiwania listy przesyła identyfikatory elementów do kolejki indeksowania Google Cloud Search i pobiera je pojedynczo na potrzeby indeksowania. Google Cloud Search obsługuje kolejki i porównuje ich zawartość, aby określić stan elementów, na przykład czy zostały usunięte z repozytorium. Więcej informacji o kolejce indeksowania Cloud Search znajdziesz w artykule Kolejka indeksowania Cloud Search.

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

Implementowanie punktu wejścia oprogramowania sprzęgającego

Punkt wejścia do łącznika to metoda main(). Głównym zadaniem tej metody jest utworzenie instancji klasy Application i wywołanie jej metody start(), aby uruchomić oprogramowanie sprzęgające.

Zanim wywołasz funkcję application.start(), użyj klasy IndexingApplication.Builder do utworzenia instancji szablonu ListingConnector. Funkcja ListingConnector przyjmuje obiekt Repository, którego metody implementujesz. Ten fragment kodu pokazuje, jak utworzyć instancję obiektu ListingConnector i powiązanego z nim obiektu 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 metody main() w kontekście połączenia Application.build. Metoda initConfig():

  1. Wywołuje metodę Configuation.isInitialized(), aby sprawdzić, czy nie została zainicjowana zmienna Configuration.
  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 przeszukiwanie i indeksowanie elementów repozytorium. Aby utworzyć łącznik treści, wystarczy zastąpić w interfejsie Repository tylko niektóre metody. Metody, które zastąpisz, zależą od używanego szablonu i strategii przeszukiwania. W przypadku pola ListingConnector zastąpij te metody:

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

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

  • metoda getDoc(). Aby dodawać nowe elementy, aktualizować, modyfikować lub usuwać elementy z indeksu, zastąpij metodę getDoc().

  • (opcjonalnie) metoda getChanges(). Jeśli repozytorium obsługuje wykrywanie zmian, zastąpij metodę getChanges(). Ta metoda jest wywoływana raz dla każdej zaplanowanej iteracyjnej iteracji (zgodnie z konfiguracją), aby pobierać zmodyfikowane elementy i je indeksować.

  • (opcjonalnie) metoda close(). Jeśli musisz wyczyścić repozytorium, zastąpij metodę close(). Ta metoda jest wywoływana raz podczas zamykania łącznika.

Każda z metod obiektu Repository zwraca obiekt typu ApiOperation. Obiekt ApiOperation wykonuje działanie w postaci pojedynczego lub wielu wywołań funkcji IndexingService.indexItem(), aby przeprowadzić faktyczne indeksowanie repozytorium.

Pobieranie parametrów konfiguracji niestandardowej

W ramach obsługi konfiguracji łącznika musisz pobrać wszystkie parametry niestandardowe z obiektu Configuration. Zwykle jest to wykonywane w ramach metody Repository klasy init().

Klasa Configuration udostępnia kilka metod służących do uzyskiwania różnych typów danych z konfiguracji. Każda metoda zwraca obiekt ConfigValue. Następnie użyjesz metody get() obiektu ConfigValue, aby pobrać rzeczywistą wartość. Ten fragment kodu z FullTraversalSample pokazuje, jak pobrać jedną 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 analizatorów typu klasy Configuration, aby przeanalizować dane na oddzielne fragmenty. Ten fragment kodu z samouczka używa metody getMultiValue do uzyskania listy nazw repozytoriów GitHub:

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

Przechodzenie po liście

Zastąp metodę getIds(), aby pobrać identyfikatory i wartości skrótów dla wszystkich rekordów w repozytorium. Metoda getIds() akceptuje punkt kontrolny. Punkt kontrolny służy do wznowienia indeksowania w przypadku przerwania procesu.

Następnie zastąpij metodę getDoc(), aby obsłużyć każdy element w kolejce indeksowania Cloud Search.

Przesyłanie identyfikatorów produktów i wartości haszowanych

Zastąp parametrgetIds(), aby pobrać z repozytorium identyfikatory elementów i powiązane z nimi wartości haszowania treści. Pary identyfikatorów i wartości hasz są następnie pakowane w operację przesyłania do kolejki indeksowania Cloud Search. Najpierw są zwykle przesyłane identyfikatory główne lub nadrzędne, a następnie identyfikatory podrzędne, aż do przetworzenia całej hierarchii elementów.

Metoda getIds() przyjmuje punkt kontrolny reprezentujący ostatni element, który ma zostać zindeksowany. W przypadku przerwania procesu możesz użyć punktu kontrolnego, aby wznowić indeksowanie konkretnego elementu. W przypadku każdego elementu w repozytorium wykonaj te kroki metody getIds():

  • Pobierz z repozytorium identyfikator każdego elementu i powiązaną z nim wartość hasz.
  • Zawijaj każdą parę identyfikatora i wartości hasha w element PushItems.
  • Połącz każdy element PushItems z iteratorem zwracanym przez metodę getIds(). Pamiętaj, że funkcja getIds() zwraca obiekt CheckpointCloseableIterable, który jest iteracją obiektów ApiOperation. Każdy z nich reprezentuje żądanie interfejsu API wykonane w RepositoryDoc, np. dodanie elementów do kolejki.

Ten fragment kodu pokazuje, jak pobrać identyfikator każdego elementu i wartość jego hasha, a następnie wstawić je do parametru PushItems. PushItems to żądanie ApiOperation, które przekazuje element 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 za pomocą klasy PushItems.Builder zapakować identyfikatory i wartości haszowane do pojedynczego pusha 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 poszczególnych elementów

ZastąpijgetDoc(), aby obsłużyć każdy element w kolejce indeksowania Cloud Search. Element może być nowy, zmodyfikowany, niezmodyfikowany lub może nie istnieć w repozytorium źródłowym. Pobierać i indeksować każdy nowy lub zmodyfikowany element. Usuń z indeksu elementy, których nie ma już w repozytorium źródłowym.

Metoda getDoc() przyjmuje element z kolejki indeksowania Google Cloud Search. W przypadku każdego elementu w kole wykonaj te czynności w ramach metody getDoc():

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

  2. Sprawdź indeks pod kątem stanu elementu. Jeśli element nie został zmieniony (ACCEPTED), nic nie rób.

  3. Zmieniony indeks lub nowe elementy:

    1. Ustaw uprawnienia.
    2. Ustaw metadane dla indeksowanego elementu.
    3. Połącz metadane i element w jeden indeksowalny element.RepositoryDoc
    4. Zwrot RepositoryDoc.

Uwaga: szablon ListingConnector nie obsługuje zwracania wartości null w ramach metody getDoc(). Zwracanie null wyników w NullPointerException.

Obsługa usuniętych elementów

Ten fragment kodu pokazuje, jak sprawdzić, czy element istnieje w archiwum, 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 documentID nie zostanie znaleziony w documents, zwracaj APIOperations.deleteItem(resourceName), aby usunąć element z indeksu.

Obsługa niezmienionych elementów

Ten fragment kodu pokazuje, jak odczytywać 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 ustalić, 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ń dotyczących elementu

Repozytorium używa listy kontroli dostępu (ACL) do identyfikowania użytkowników lub grup, 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 powielić reguły ACL używane przez repozytorium, aby mieć pewność, że tylko użytkownicy z dostępem do danego elementu będą mogli go zobaczyć w wynikach wyszukiwania. Podczas indeksowania elementu należy uwzględnić jego listę ACL, aby Google Cloud Search miał informacje potrzebne do zapewnienia odpowiedniego poziomu dostępu do elementu.

Pakiet SDK Content Connector udostępnia bogaty zestaw klas i metod 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 ACL repozytorium korzysta z takich pojęć jak dziedziczenie listy ACL, modelowanie tej listy może być trudne. Więcej informacji o regułach dostępu w Google Cloud Search znajdziesz w artykule Reguły dostępu w Google Cloud Search.

Uwaga: interfejs Cloud Search Indexing API obsługuje uprawnienia ACL dla jednej domeny. Nie obsługuje list ACL między domenami. Użyj klasy Acl.Builder, aby ustawić dostęp do poszczególnych elementów za pomocą listy kontroli dostępu. Poniższy fragment kodu pochodzący z pełnego przykładu przeszukiwania umożliwia wszystkim użytkownikom lub „podmiotom” (getCustomerPrincipal()) być „czytnikami” 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 w repozytorium, musisz je dobrze rozumieć. Na przykład możesz indeksować pliki w systemie plików, który używa pewnego modelu dziedziczenia, w którym foldery podrzędne dziedziczą uprawnienia z folderów nadrzędnych. Modelowanie dziedziczenia uprawnień wymaga dodatkowych informacji, które znajdziesz w artykule Uprawnienia dostępu w Google Cloud Search.

Ustawianie metadanych produktu

Metadane są przechowywane w obiekcie Item. Aby utworzyć element Item, musisz podać 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 podlegającego indeksowaniu

Po ustawieniu metadanych elementu możesz utworzyć rzeczywisty indeksowalny element za pomocą elementu RepositoryDoc.Builder. W tym przykładzie pokazujemy, jak utworzyć pojedynczy indeksowalny element.

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 typ ApiOperation , który wykonuje rzeczywiste żądanie IndexingService.indexItem().

Możesz też użyć metody setRequestMode() klasy RepositoryDoc.Builder, aby zidentyfikować żądanie indeksowania jako ASYNCHRONOUS lub SYNCHRONOUS:

ASYNCHRONOUS
Tryb asynchroniczny powoduje dłuższy czas od indeksowania do wyświetlania i umożliwia stosowanie dużego limitu przepustowości dla żądań indeksowania. Tryb asynchroniczny jest zalecany do początkowego indeksowania (uzupełniania) całego repozytorium.
SYNCHRONOUS
Tryb synchroniczny powoduje krótsze opóźnienie między indeksowaniem a wyświetlaniem i umożliwia korzystanie z ograniczonej puli przepustowości. Tryb synchroniczny jest zalecany do indeksowania aktualizacji i zmian w repozytorium. Jeśli nie określisz trybu żądania, zostanie użyte ustawienie domyślne SYNCHRONOUS.

Następne kroki

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

Tworzenie złącza do przeszukiwania grafu za pomocą klasy szablonu

Kolejka indeksowania Cloud Search służy do przechowywania identyfikatorów i opcjonalnych wartości haszowanych dla każdego elementu w repozytorium. Połączenie z przeszukiwaniem grafu przesyła identyfikatory elementów do kolejki indeksowania Google Cloud Search i pobiera je pojedynczo na potrzeby indeksowania. Google Cloud Search obsługuje kolejki i porównuje ich zawartość, aby określić stan elementów, np. czy zostały usunięte z repozytorium. Więcej informacji o kole indeksowania Cloud Search znajdziesz w artykule Kole indeksowania Google Cloud Search.

Podczas indeksowania treści produktu są pobierane z repozytorium danych, a identyfikatory podrzędnych produktów są dodawane do kolejki. Połączenie działa rekurencyjnie, przetwarzając identyfikatory nadrzędne i podrzędne, dopóki nie zostaną przetworzone wszystkie elementy.

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

Implementacja punktu wejścia oprogramowania sprzęgającego

Punkt wejścia do łącznika to metoda main(). Głównym zadaniem tej metody jest utworzenie instancji klasy Application i wywołanie jej metody start(), aby uruchomić oprogramowanie sprzęgające.

Zanim wywołasz funkcję application.start(), użyj klasy IndexingApplication.Builder, aby utworzyć instancję szablonu ListingConnector. Funkcja ListingConnector przyjmuje obiekt Repository, którego metody implementujesz.

Ten fragment kodu pokazuje, jak utworzyć instancję obiektu ListingConnector i powiązanego z nim obiektu 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 metody main() w kontekście połączenia Application.build. Metoda initConfig():

  1. Wywołuje metodę Configuation.isInitialized(), aby sprawdzić, czy nie została zainicjowana zmienna Configuration.
  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 przeszukiwanie i indeksowanie elementów repozytorium. Aby utworzyć łącznik treści, wystarczy zastąpić określone metody w interfejsie Repository. Metody, które zastąpisz, zależą od używanego szablonu i strategii przeszukiwania. W przypadku elementu ListingConnector zastąpisz te metody:

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

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

  • metoda getDoc(). Aby dodawać nowe elementy, aktualizować, modyfikować lub usuwać elementy z indeksu, zastąpij metodę getDoc().

  • (opcjonalnie) metoda getChanges(). Jeśli repozytorium obsługuje wykrywanie zmian, zastąpij metodę getChanges(). Ta metoda jest wywoływana raz dla każdej zaplanowanej iteracyjnej iteracji (zgodnie z konfiguracją), aby pobierać zmodyfikowane elementy i je indeksować.

  • (opcjonalnie) metoda close(). Jeśli musisz wyczyścić repozytorium, zastąpij metodę close(). Ta metoda jest wywoływana raz podczas zamykania łącznika.

Każda z metod obiektu Repository zwraca obiekt typu ApiOperation. Obiekt ApiOperation wykonuje działanie w postaci pojedynczego lub wielu wywołań IndexingService.indexItem(), aby przeprowadzić indeksowanie repozytorium.

Pobieranie parametrów konfiguracji niestandardowej

W ramach obsługi konfiguracji łącznika musisz pobrać wszystkie parametry niestandardowe z obiektu Configuration. Zwykle jest to wykonywane w ramach metody Repository klasy init().

Klasa Configuration udostępnia kilka metod służących do uzyskiwania różnych typów danych z konfiguracji. Każda metoda zwraca obiekt ConfigValue. Następnie użyjesz metody get() obiektu ConfigValue, aby pobrać rzeczywistą wartość. Ten fragment kodu z FullTraversalSample pokazuje, jak pobrać jedną 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 analizatorów typu klasy Configuration, aby przeanalizować dane na oddzielne fragmenty. Ten fragment kodu z samouczka używa metody getMultiValue do uzyskania listy nazw repozytoriów GitHub:

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

Przechodzenie po grafie

Zastąp metodę getIds(), aby pobrać identyfikatory i wartości skrótów dla wszystkich rekordów w repozytorium. Metoda getIds() akceptuje punkt kontrolny. Punkt kontrolny służy do wznowienia indeksowania w przypadku przerwania procesu.

Następnie zastąpij metodę getDoc(), aby obsłużyć każdy element w kolejce indeksowania Cloud Search.

Przesyłanie identyfikatorów produktów i wartości haszowanych

Zastąp parametrgetIds(), aby pobrać z repozytorium identyfikatory elementów i powiązane z nimi wartości haszowania treści. Pary identyfikatorów i wartości hasha są następnie pakowane w operację przesyłania do kolejki indeksowania Cloud Search. Najpierw są zwykle przesyłane identyfikatory główne lub nadrzędne, a następnie identyfikatory podrzędne, aż do przetworzenia całej hierarchii elementów.

Metoda getIds() przyjmuje punkt kontrolny reprezentujący ostatni element, który ma zostać zindeksowany. W przypadku przerwania procesu możesz użyć punktu kontrolnego, aby wznowić indeksowanie konkretnego elementu. W przypadku każdego elementu w repozytorium wykonaj te kroki metody getIds():

  • Pobierz z repozytorium identyfikator każdego elementu i powiązaną z nim wartość hasz.
  • Zawijaj każdą parę identyfikatora i wartości hasha w element PushItems.
  • Połącz każdy element PushItems z iteratorem zwracanym przez metodę getIds(). Pamiętaj, że funkcja getIds() zwraca obiekt CheckpointCloseableIterable, który jest iteracją obiektów ApiOperation. Każdy z nich reprezentuje żądanie interfejsu API wykonane w RepositoryDoc, np. dodanie elementów do kolejki.

Ten fragment kodu pokazuje, jak pobrać identyfikator każdego produktu i wartość hasha, a następnie wstawić je do PushItems. PushItems to ApiOperation, czyli żądanie przesłania elementu do kolejki indeksowania Cloud Search.

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

Ten fragment kodu pokazuje, jak za pomocą klasy PushItems.Builder zapakować identyfikatory i wartości haszowane w jednym pushu 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 poszczególnych elementów

ZastąpijgetDoc(), aby obsłużyć każdy element w kolejce indeksowania Cloud Search. Element może być nowy, zmodyfikowany, niezmodyfikowany lub może nie istnieć w repozytorium źródłowym. Pobierać i indeksować każdy nowy lub zmodyfikowany element. Usuń z indeksu elementy, których nie ma już w repozytorium źródłowym.

Metoda getDoc() przyjmuje element z kolejki indeksowania Cloud Search. W przypadku każdego elementu w kole wykonaj te czynności w ramach metody getDoc():

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

  2. Zmieniony indeks lub nowe elementy:

    1. Ustaw uprawnienia.
    2. Ustaw metadane dla indeksowanego elementu.
    3. Połącz metadane i element w jeden indeksowalny element.RepositoryDoc
    4. Umieść identyfikatory podrzędne w kolejce indeksowania Cloud Search, aby przetworzyć je dalej.
    5. Zwrot RepositoryDoc.

Obsługa usuniętych elementów

Ten 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ń dotyczących elementu

Repozytorium używa listy kontroli dostępu (ACL) do identyfikowania użytkowników lub grup, 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 powielić reguły ACL używane przez repozytorium, aby mieć pewność, że tylko użytkownicy z dostępem do danego elementu będą mogli go zobaczyć w wynikach wyszukiwania. Podczas indeksowania elementu należy uwzględnić jego listę ACL, aby Google Cloud Search miał informacje potrzebne do zapewnienia odpowiedniego poziomu dostępu do elementu.

Pakiet SDK Content Connector udostępnia bogaty zestaw klas i metod 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 ACL repozytorium korzysta z takich pojęć jak dziedziczenie listy ACL, modelowanie tej listy może być trudne. Więcej informacji o zasadach dostępu w Google Cloud Search znajdziesz w artykule Zasady dostępu w Google Cloud Search.

Uwaga: interfejs Cloud Search Indexing API obsługuje uprawnienia ACL w ramach jednej domeny. Nie obsługuje list ACL między domenami. Użyj klasy Acl.Builder, aby ustawić dostęp do poszczególnych elementów za pomocą listy kontroli dostępu. Poniższy fragment kodu pochodzący z pełnego przykładu przeszukiwania umożliwia wszystkim użytkownikom lub „podmiotom” (getCustomerPrincipal()) być „czytnikami” 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 w repozytorium, musisz je dobrze rozumieć. Na przykład możesz indeksować pliki w systemie plików, który używa pewnego modelu dziedziczenia, w którym foldery podrzędne dziedziczą uprawnienia z folderów nadrzędnych. Modelowanie dziedziczenia uprawnień wymaga dodatkowych informacji, które znajdziesz w artykule Uprawnienia dostępu w Google Cloud Search.

Ustawianie metadanych produktu

Metadane są przechowywane w obiekcie Item. Aby utworzyć element Item, musisz podać 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 podlegającego indeksowaniu

Po ustawieniu metadanych elementu możesz utworzyć rzeczywisty indeksowalny element za pomocą elementu RepositoryDoc.Builder. W tym przykładzie pokazujemy, jak utworzyć pojedynczy indeksowalny element.

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 typ ApiOperation, który wykonuje rzeczywiste żądanie IndexingService.indexItem().

Możesz też użyć metody setRequestMode() klasy RepositoryDoc.Builder, aby zidentyfikować żądanie indeksowania jako ASYNCHRONOUS lub SYNCHRONOUS:

ASYNCHRONOUS
Tryb asynchroniczny powoduje dłuższy czas od indeksowania do wyświetlania i umożliwia stosowanie dużego limitu przepustowości dla żądań indeksowania. Tryb asynchroniczny jest zalecany do początkowego indeksowania (uzupełniania) całego repozytorium.
SYNCHRONOUS
Tryb synchroniczny powoduje krótsze opóźnienie między indeksowaniem a wyświetlaniem i umożliwia korzystanie z ograniczonej puli przepustowości. Tryb synchroniczny jest zalecany do indeksowania aktualizacji i zmian w repozytorium. Jeśli nie określisz trybu żądania, zostanie użyte ustawienie domyślne SYNCHRONOUS.

umieszczanie identyfikatorów podrzędnych w kolejce indeksowania Cloud Search.

Ten fragment kodu pokazuje, jak uwzględnić identyfikatory podrzędnych elementów w kole do przetwarzania dla obecnie przetwarzanego elementu nadrzędnego. 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 wykonać:

  • (opcjonalnie) Zaimplementuj metodę close(), aby zwolnić wszystkie zasoby przed wyłączeniem.
  • (opcjonalnie) utwórz łącznik tożsamości za pomocą pakietu SDK łącznika tożsamości.

Tworzenie oprogramowania sprzęgającego treści za pomocą interfejsu API REST

W kolejnych sekcjach opisujemy, jak utworzyć oprogramowanie sprzęgające treści za pomocą interfejsu API REST.

Określanie strategii przeszukiwania

Podstawową funkcją łącznika treści jest przeszukiwanie repozytorium i indeksowanie jego danych. Musisz zastosować strategię przeszukiwania na podstawie rozmiaru i układu danych w repozytorium. Oto 3 popularne strategie przeszukiwania:

Strategia pełnego przeszukiwania

Strategia pełnego przeszukiwania skanuje całe repozytorium i indeksuje wszystkie elementy. Ta strategia jest często stosowana, gdy masz małe repozytorium i możesz sobie pozwolić na obciążenie związane z pełnym przeszukiwaniem za każdym razem, gdy indeksujesz.

Ta strategia przeszukiwania jest odpowiednia w przypadku małych repozytoriów z głównie statycznymi, niehierarchicznymi danymi. Możesz też użyć tej strategii przeszukiwania, gdy wykrywanie zmian jest trudne lub nieobsługiwane przez repozytorium.

List traversal strategy

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

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

Przeglądanie grafu

Strategia przeszukiwania grafu skanuje cały węzeł nadrzędny, aby określić stan każdego elementu. Następnie oprogramowanie sprzęgające wykonuje drugi przejazd i indeksuje tylko te elementy w węźle głównym, które są nowe lub zostały zaktualizowane od czasu ostatniego indeksowania. Na koniec usługa przekazuje wszystkie identyfikatory elementów podrzędnych, a następnie indeksuje elementy w węzłach podrzędnych, które są nowe lub zostały zaktualizowane. Połączenie przechodzi rekurencyjnie przez wszystkie węzły podrzędne, dopóki nie zostaną przetworzone wszystkie elementy. Takie przeszukiwanie 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 hierarchicznej, które wymagają zindeksowania, np. katalogi serii lub strony internetowe.

Wdrażanie strategii przeszukiwania i indeksowania elementów

Każdy indeksowany element w Cloud Search jest w Cloud Search API nazywany elementem. Element może być plikiem, folderem, wierszem w pliku CSV lub rekordem w bazie danych.

Gdy schemat zostanie zarejestrowany, możesz wypełnić indeks, wykonując te czynności:

  1. (opcjonalnie) Użyj polecenia items.upload, aby przesłać pliki większe niż 100 KiB na potrzeby indeksowania. W przypadku mniejszych plików osadzaj je za pomocą atrybutu inlineContent, używając atrybutu 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życie wywołań items.get, aby sprawdzić, czy element został zindeksowany.

Aby przeprowadzić pełne przeszukiwanie, musisz okresowo ponownie zindeksować całe repozytorium. Aby przeprowadzić skanowanie listy lub grafu, 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. Chociaż pełne indeksowanie zapewnia aktualność indeksu, może być kosztowne w przypadku większych lub hierarchicznych repozytoriów.

Zamiast używać wywołań indeksu do indeksowania całej repozytorium co jakiś czas możesz też użyć kolejki indeksowania Google Cloud jako mechanizmu śledzenia zmian i indeksowania tylko tych elementów, które się zmieniły. Za pomocą żądań items.push możesz przesyłać elementy do kolejki w celu późniejszego pobierania i aktualizowania. Więcej informacji o kolejce indeksowania Google Cloud znajdziesz w artykule Kolejka indeksowania Google Cloud.

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