יצירת מחבר של תוכן

מחבר תוכן הוא תוכנה שסורקת נתונים במאגר ארגוני ומאכלסת מקור נתונים. ‫Google מספקת את האפשרויות הבאות לפיתוח מחברי תוכן:

  • ‫Content Connector SDK. האפשרות הזו מתאימה למתכנתי Java. ה-SDK הוא מעטפת סביב REST API שמאפשרת ליצור מחברים במהירות. כדי ליצור מחבר תוכן באמצעות ה-SDK, אפשר לעיין במאמר יצירת מחבר תוכן באמצעות Content Connector SDK.

  • ‫API ל-REST ברמה נמוכה או ספריות API. כדאי להשתמש באפשרויות האלה אם אתם לא משתמשים ב-Java או אם בסיס הקוד שלכם מתאים יותר ל-API ל-REST או לספרייה. כדי ליצור מחבר תוכן באמצעות REST API, אפשר לעיין במאמר יצירת מחבר תוכן באמצעות REST API.

מחבר תוכן טיפוסי מבצע את המשימות הבאות:

  1. קריאה ועיבוד של פרמטרים של הגדרות.
  2. שולף נתונים נפרדים שניתנים להוספה לאינדקס, שנקראים פריטים, ממאגר של צד שלישי.
  3. משלב רשימות ACL, מטא-נתונים ונתוני תוכן בפריטים שניתן להוסיף לאינדקס.
  4. הוספת פריטים לאינדקס במקור הנתונים של Cloud Search.
  5. (אופציונלי) המערכת מאזינה להתראות על שינויים במאגר. שינויים בהתראות הופכים לבקשות ליצירת אינדקס כדי לשמור על סנכרון של מקור הנתונים ב-Cloud Search. המחבר מבצע את המשימה הזו רק אם המאגר תומך בזיהוי שינויים.

יצירת מחבר תוכן באמצעות Content Connector SDK

בקטעים הבאים מוסבר איך ליצור מחבר תוכן באמצעות Content Connector SDK.

הגדרת יחסי תלות

כוללים את התלויות האלה בקובץ ה-build.

Maven

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

Gradle

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

יצירת הגדרות של מחבר

כל מחבר משתמש בקובץ הגדרה לפרמטרים כמו מזהה המאגר. מגדירים פרמטרים כצמדים של מפתח-ערך, כמו api.sourceId=1234567890abcdef.

ערכת ה-SDK של Google Cloud Search כוללת פרמטרים שסופקו על ידי Google לכל המחברים. צריך להצהיר על הפרטים הבאים בקובץ ההגדרות:

  • מחבר תוכן: צריך להצהיר על api.sourceId ועל api.serviceAccountPrivateKeyFile. הם מזהים את המאגר ואת המפתח הפרטי שנדרש לגישה.
  • מחבר זהויות: צריך להצהיר על api.identitySourceId כדי לזהות את מקור הזהויות החיצוני. לסנכרון משתמשים, צריך גם להצהיר על api.customerId (המזהה הייחודי של חשבון Google Workspace).

מצהירים על פרמטרים אחרים שסופקו על ידי Google רק כדי לשנות את ערכי ברירת המחדל שלהם. פרטים על יצירת מזהים ומפתחות זמינים במאמר בנושא פרמטרים שסופקו על ידי Google.

אפשר גם להגדיר פרמטרים ספציפיים למאגר בקובץ ההגדרות.

העברת קובץ התצורה למחבר

מגדירים את מאפיין המערכת config כדי להעביר את קובץ התצורה. משתמשים בארגומנט -D כשמפעילים את המחבר. לדוגמה:

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

אם לא מציינים את הארגומנט הזה, ערכת ה-SDK מנסה להשתמש בקובץ בשם connector-config.properties בספרייה המקומית.

קביעת אסטרטגיית המעבר

התפקיד העיקרי של מחבר תוכן הוא לסרוק מאגר ולאנדקס את הנתונים שלו. צריך להטמיע אסטרטגיה על סמך הגודל והפריסה של המאגר. אתם יכולים לעצב אסטרטגיה משלכם או לבחור אסטרטגיה מתוך ה-SDK:

אסטרטגיית מעבר מלאה
סורק את כל המאגר ומבצע אינדוקס של כל פריט. השיטה הזו מתאימה במיוחד למאגרים קטנים שבהם אפשר להרשות לעצמכם את התקורה של סריקה מלאה במהלך כל אינדוקס. מומלץ להשתמש בו למאגרי מידע קטנים עם נתונים סטטיים ברובם, לא היררכיים, או כשקשה לזהות שינויים.
אסטרטגיה למעבר בין רשימות
סורק את כל המאגר כדי לקבוע את הסטטוס של כל פריט, ואז יוצר אינדקס רק לפריטים חדשים או מעודכנים. אפשר להשתמש באפשרות הזו לעדכונים מצטברים של אינדקס גדול ולא היררכי, כשזיהוי שינויים לא נתמך.
מעבר בין צמתים בגרף
סורק צומת אב כדי לקבוע את הסטטוס של הפריטים שלו, ואז מוסיף לאינדקס פריטים חדשים או מעודכנים בצומת הזה. לאחר מכן, הוא מעבד באופן רקורסיבי צמתים משניים. אפשר להשתמש בזה במאגרי מידע היררכיים שבהם לא מעשי לפרט את כל המזהים, כמו מבני ספריות או אתרים.

ה-SDK מטמיע את האסטרטגיות האלה במחלקות של מחברי תבניות. התבניות האלה יכולות להאיץ את הפיתוח. כדי להשתמש בתבנית, אפשר לעיין בקטע המתאים:

יצירת מחבר לסריקה מלאה באמצעות מחלקת תבנית

הקטע הזה מתייחס לקוד מתוך FullTraversalSample.

הטמעה של נקודת הכניסה למחבר

נקודת הכניסה היא השיטה main(). הוא יוצר מופע של Application ומפעיל את המחבר באמצעות start().

לפני ששולחים קריאה ל-application.start(), משתמשים במחלקה IndexingApplication.Builder כדי ליצור מופע של התבנית FullTraversalConnector. התבנית הזו מקבלת אובייקט Repository.

FullTraversalSample.java
/**
 * This sample connector uses the Cloud Search SDK template class for a full
 * traversal connector.
 *
 * @param args program command line arguments
 * @throws InterruptedException thrown if an abort is issued during initialization
 */
public static void main(String[] args) throws InterruptedException {
  Repository repository = new SampleRepository();
  IndexingConnector connector = new FullTraversalConnector(repository);
  IndexingApplication application = new IndexingApplication.Builder(connector, args).build();
  application.start();
}

ערכת ה-SDK שולחת קריאה ל-initConfig() אחרי שמתבצעות קריאות ל-method main() שלכם Application.build(). השיטה initConfig():

  1. מוודאים שהרכיב Configuration לא אותחל כבר.
  2. הפונקציה מאתחלת את האובייקט Configuration עם צמדי מפתח/ערך שסופקו על ידי Google.

הטמעה של ממשק המאגר

האובייקט Repository סורק ומבצע אינדוקס של פריטים במאגר. כשמשתמשים בתבנית, צריך לעקוף רק שיטות מסוימות בממשק Repository. ל-FullTraversalConnector, שינוי מברירת המחדל:

  • init(): להגדרה ולאתחול של מאגר.
  • getAllDocs(): כדי לסרוק את כל הפריטים ולהוסיף אותם לאינדקס. הפונקציה הזו מופעלת פעם אחת לכל מעבר מתוזמן.
  • (אופציונלי) getChanges(): אם המאגר תומך בזיהוי שינויים, אפשר לבטל את ההגדרה הזו כדי לאחזר ולאנדקס פריטים שעברו שינוי.
  • (אופציונלי) close(): לניקוי המאגר במהלך הכיבוי.

כל שיטה מחזירה אובייקט ApiOperation שמבצע אינדוקס באמצעות IndexingService.indexItem().

אחזור פרמטרים של הגדרה בהתאמה אישית

כדי לטפל בהגדרת המחבר, צריך לאחזר את כל הפרמטרים המותאמים אישית מאובייקט Configuration. מבצעים את המשימה הזו בשיטה init() של הכיתה Repository.

המחלקות Configuration כוללות שיטות לאחזור סוגים שונים של נתונים. כל שיטה מחזירה אובייקט ConfigValue. כדי לאחזר את הערך, משתמשים ב-method get() של האובייקט ConfigValue. בקטע הקוד הבא מתוך FullTraversalSample אפשר לראות איך מאחזרים ערך של מספר שלם בהתאמה אישית:

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

כדי לאחזר ולנתח פרמטרים עם כמה ערכים, צריך להשתמש באחד ממנתחי הסוגים של המחלקה Configuration. בקטע הקוד הזה מתוך מחבר הנתונים של המדריך נעשה שימוש ב-getMultiValue כדי לאחזר רשימה של שמות מאגרי GitHub:

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

ביצוע סריקה מלאה

אפשר להשתמש ב-Override getAllDocs() כדי לבצע מעבר מלא. השיטה הזו מקבלת נקודת ביקורת כדי לחדש את יצירת האינדקס אם היא מופרעת. לכל פריט:

  1. מגדירים הרשאות.
  2. מגדירים מטא-נתונים.
  3. משלבים אותם לRepositoryDoc.
  4. אורזים כל פריט באיטרטור שמוחזר על ידי getAllDocs().

אם קבוצת הפריטים גדולה מדי בשביל קריאה אחת, צריך להשתמש בנקודת ביקורת ולהתקשר אל hasMore(true).

הגדרת ההרשאות לפריט

מאגרי מידע משתמשים ברשימות של בקרת גישה (ACL) כדי לזהות משתמשים או קבוצות עם גישה לפריט. רשימת ACL כוללת את המזהים של משתמשים או קבוצות מורשים.

כדי לוודא שהמשתמשים יראו רק תוצאות חיפוש שיש להם הרשאה לגשת אליהן, צריך לשכפל את רשימות בקרת הגישה (ACL) של המאגר. כדאי לכלול את רשימת ה-ACL כשמוסיפים פריט לאינדקס, כדי ש-Google Cloud Search יוכל לספק את רמת הגישה הנכונה.

ערכת Content Connector SDK כוללת מחלקות ושיטות ליצירת מודלים של ACL ברוב המאגרים. ניתוח של רשימות בקרת הגישה (ACL) של המאגר ויצירה של רשימות בקרת גישה תואמות עבור Cloud Search במהלך הוספה לאינדקס. כדי ליצור מודלים של רשימות ACL מורכבות, כמו אלה שמשתמשות בירושה, צריך לתכנן בקפידה. מידע נוסף זמין במאמר רשימות ACL ב-Cloud Search.

משתמשים במחלקה Acl.Builder כדי להגדיר גישה. קטע הקוד הזה מתוך דוגמה מלאה של מעבר מאפשר לכל המשתמשים בדומיין (getCustomerPrincipal()) לקרוא את כל הפריטים (setReaders()):

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

כדי ליצור מודל נכון של רשימות ACL במאגר, במיוחד אם משתמשים במודלים של ירושה, צריך את המידע שמופיע במאמר רשימות ACL ב-Cloud Search.

הגדרת המטא-נתונים של פריט

המטא-נתונים מאוחסנים באובייקט Item. כדי ליצור Item, צריך מזהה ייחודי, סוג פריט, רשימת ACL, כתובת URL וגרסה. משתמשים במחלקה 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();
יצירת הפריט שאפשר להוסיף לאינדקס

משתמשים בכיתה RepositoryDoc.Builder.

FullTraversalSample.java
// For this sample, content is just plain text
String content = String.format("Hello world from sample doc %d", id);
ByteArrayContent byteContent = ByteArrayContent.fromString("text/plain", content);

// Create the fully formed document
RepositoryDoc doc = new RepositoryDoc.Builder()
    .setItem(item)
    .setContent(byteContent, IndexingService.ContentFormat.TEXT)
    .build();

RepositoryDoc הוא ApiOperation שמבצע את בקשת IndexingService.indexItem().

משתמשים ב-method‏ setRequestMode() של המחלקה RepositoryDoc.Builder כדי להגדיר את בקשת ההוספה לאינדקס ל-ASYNCHRONOUS או ל-SYNCHRONOUS:

ASYNCHRONOUS
במצב הזה, זמן האחזור בין יצירת האינדקס לבין הצגת התוצאות ארוך יותר, אבל המכסה של קצב העברת הנתונים גדולה יותר. להשתמש במצב אסינכרוני לאינדוקס ראשוני (backfill) של מאגר שלם.
SYNCHRONOUS
במצב הזה זמן האחזור בין יצירת האינדקס לבין הצגת התוצאות קצר יותר, אבל מכסת התפוקה קטנה יותר. משתמשים במצב סינכרוני כדי להוסיף לאינדקס עדכונים ושינויים במאגר. אם לא מציינים את מצב הבקשה, ברירת המחדל היא SYNCHRONOUS.
אורזים כל פריט שאפשר להוסיף לאינדקס באיטרטור

השיטה getAllDocs() מחזירה CheckpointCloseableIterable של אובייקטים מסוג RepositoryDoc. משתמשים בכיתה CheckpointCloseableIterableImpl.Builder.

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

השלבים הבאים

יצירת מחבר למעבר על רשימה באמצעות מחלקת תבנית

תור ההוספה לאינדקס של Cloud Search מכיל מזהים וגיבובים אופציונליים של פריטים במאגר. מחבר של מעבר על רשימה דוחף מזהים לתור הזה ומאחזר אותם לצורך יצירת אינדקס. מערכת Cloud Search מתחזקת את התורים האלה כדי לקבוע את סטטוס הפריטים, כמו מחיקות. התור של ניהול האינדקס ב-Cloud Search

הקטע הזה מתייחס ל-ListTraversalSample.

הטמעה של נקודת הכניסה למחבר

השיטה main() יוצרת מופע Application וקוראת ל-start(). משתמשים ב-IndexingApplication.Builder כדי ליצור מופע של התבנית ListingConnector.

ListTraversalSample.java
/**
 * This sample connector uses the Cloud Search SDK template class for a
 * list traversal connector.
 *
 * @param args program command line arguments
 * @throws InterruptedException thrown if an abort is issued during initialization
 */
public static void main(String[] args) throws InterruptedException {
  Repository repository = new SampleRepository();
  IndexingConnector connector = new ListingConnector(repository);
  IndexingApplication application = new IndexingApplication.Builder(connector, args).build();
  application.start();
}

הטמעה של ממשק המאגר

מחליפים את השיטות הבאות עבור ListingConnector:

  • init(): להגדרת מאגר.
  • getIds(): כדי לאחזר מזהים וגיבובים של כל הרשומות.
  • getDoc(): כדי להוסיף, לעדכן או למחוק פריטים מהאינדקס.
  • (אופציונלי) getChanges(): לעדכונים מצטברים באמצעות זיהוי שינויים.
  • (אופציונלי) close(): לניקוי המאגר.

ביצוע מעבר ברשימה

מחליפים את getIds() כדי לאחזר מזהים וגיבובים. מחליפים את getDoc() כדי לטפל בכל פריט בתור של Cloud Search Indexing.

שליחת מזהי פריטים וערכי גיבוב

מחליפים את getIds() כדי לאחזר מזהים וגיבובי תוכן. אורזים אותם בבקשה ל-PushItems לתור ההוספה לאינדקס.

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

משתמשים ב-PushItems.Builder כדי לארוז את המזהים והגיבובים.

ListTraversalSample.java
ApiOperation pushOperation = allIds.build();
CheckpointCloseableIterable<ApiOperation> iterator =
  new CheckpointCloseableIterableImpl.Builder<>(
      Collections.singletonList(pushOperation))
  .build();
return iterator;
אחזור וטיפול בכל פריט

אפשר להגדיר חריגה getDoc() כדי לטפל בפריטים בתור ליצירת אינדקס. הפריטים יכולים להיות חדשים, שעברו שינוי, שלא השתנו או שנמחקו.

  1. בודקים אם מזהה הפריט קיים במאגר. אם לא, מוחקים אותו.
  2. שולחים שאילתה לאינדקס כדי לבדוק את הסטטוס. אם לא משנים את הערך (ACCEPTED), לא מתבצעת פעולה.
  3. פריטים חדשים או פריטים ששונו באינדקס: הגדרת הרשאות, הגדרת מטא-נתונים, שילוב לתוך RepositoryDoc והחזרתם.
טיפול בפריטים שנמחקו

בקטע הקוד הבא אפשר לראות איך בודקים אם פריט קיים ומוחקים אותו אם הוא לא קיים.

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);
}
טיפול בפריטים שלא השתנו

מבצעים סקר של תור יצירת האינדקס כדי לטפל בפריטים שלא השתנו.

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

בדוגמה נעשה שימוש בגיבוב כדי לזהות שינויים.

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);
}
הגדרת ההרשאות לפריט

מאגרי מידע משתמשים ברשימות של בקרת גישה (ACL) כדי לזהות משתמשים או קבוצות עם גישה לפריט. רשימת ACL כוללת את המזהים של משתמשים או קבוצות מורשים.

כדי לוודא שהמשתמשים יראו רק תוצאות חיפוש שיש להם הרשאה לגשת אליהן, צריך לשכפל את רשימות בקרת הגישה (ACL) של המאגר. כדאי לכלול את רשימת ה-ACL כשמוסיפים פריט לאינדקס, כדי ש-Google Cloud Search יוכל לספק את רמת הגישה הנכונה.

ערכת Content Connector SDK כוללת מחלקות ושיטות ליצירת מודלים של ACL ברוב המאגרים. ניתוח של רשימות בקרת הגישה (ACL) של המאגר ויצירה של רשימות בקרת גישה תואמות עבור Cloud Search במהלך הוספה לאינדקס. כדי ליצור מודלים של רשימות ACL מורכבות, כמו אלה שמשתמשות בירושה, צריך לתכנן בקפידה. מידע נוסף זמין במאמר רשימות ACL ב-Cloud Search.

משתמשים במחלקה Acl.Builder כדי להגדיר גישה. קטע הקוד הזה מתוך דוגמה מלאה של מעבר מאפשר לכל המשתמשים בדומיין (getCustomerPrincipal()) לקרוא את כל הפריטים (setReaders()):

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

כדי ליצור מודל נכון של רשימות ACL במאגר, במיוחד אם משתמשים במודלים של ירושה, צריך את המידע שמופיע במאמר רשימות ACL ב-Cloud Search.

הגדרת המטא-נתונים של פריט
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();
יצירת פריט שניתן להוסיף לאינדקס
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();

משתמשים ב-method‏ setRequestMode() של המחלקה RepositoryDoc.Builder כדי להגדיר את בקשת ההוספה לאינדקס ל-ASYNCHRONOUS או ל-SYNCHRONOUS:

ASYNCHRONOUS
במצב הזה, זמן האחזור בין יצירת האינדקס לבין הצגת התוצאות ארוך יותר, אבל המכסה של קצב העברת הנתונים גדולה יותר. להשתמש במצב אסינכרוני לאינדוקס ראשוני (backfill) של מאגר שלם.
SYNCHRONOUS
במצב הזה זמן האחזור בין יצירת האינדקס לבין הצגת התוצאות קצר יותר, אבל מכסת התפוקה קטנה יותר. משתמשים במצב סינכרוני כדי להוסיף לאינדקס עדכונים ושינויים במאגר. אם לא מציינים את מצב הבקשה, ברירת המחדל היא SYNCHRONOUS.

השלבים הבאים

הנה כמה פעולות אפשריות:

  • (אופציונלי) מטמיעים את השיטה close() כדי לשחרר משאבים לפני כיבוי.
  • (אופציונלי) יוצרים מחבר זהויות באמצעות Content Connector SDK.

יצירת מחבר למעבר בין צמתים בגרף באמצעות מחלקת תבנית

תור ההמתנה להוספה לאינדקס ב-Cloud Search מכיל מזהים וערכי hash אופציונליים לכל פריט במאגר. מחבר של מעבר גרף דוחף מזהי פריטים לתור ההוספה לאינדקס של Google Cloud Search, ומאחזר אותם אחד בכל פעם לצורך הוספה לאינדקס. מערכת Google Cloud Search מתחזקת תורים ומשווה את התוכן שלהם כדי לקבוע את סטטוס הפריט, למשל אם פריט נמחק מהמאגר. מידע נוסף על תור ההוספה לאינדקס של Cloud Search זמין במאמר תור ההוספה לאינדקס של Google Cloud Search.

במהלך יצירת האינדקס, התוכן של הפריט מאוחזר ממאגר הנתונים, וכל מזהי הפריטים המשויכים נדחפים לתור. המחבר מעבד באופן רקורסיבי מזהים של הורה וצאצא עד שכל הפריטים מטופלים.

הטמעה של נקודת הכניסה של המחבר

נקודת הכניסה למחבר היא השיטה main(). ה-method הזה יוצר מופע של המחלקה Application ומפעיל את ה-method start() שלה כדי להריץ את המחבר.

לפני שמפעילים את application.start(), צריך להשתמש במחלקה IndexingApplication.Builder כדי ליצור מופע של התבנית ListingConnector. הפונקציה ListingConnector מקבלת אובייקט Repository שאת השיטות שלו אתם מטמיעים.

הטמעה של ממשק המאגר

אפשר לשנות את init(), ‏getIds(), ‏getDoc(), ואם רוצים גם את getChanges() או close().

ביצוע מעבר בין צמתים בגרף

מחליפים את getIds() כדי לאחזר מזהים ראשוניים ואת getDoc() כדי לטפל בפריטים ולהעביר מזהים של ילדים לתור.

שליחת מזהי פריטים וערכי גיבוב
GraphTraversalSample.java
PushItems.Builder allIds = new PushItems.Builder();
PushItem item = new PushItem();
allIds.addPushItem("root", item);
אחזור וטיפול בכל פריט
  1. בודקים אם המזהה קיים במאגר. אם לא, מוחקים את הפריט.
  2. לפריטים קיימים, מגדירים הרשאות ומטא-נתונים ומשלבים אותם ב-RepositoryDoc.
  3. שליחת מזהי צאצא לתור של יצירת האינדקס.
  4. החזרת RepositoryDoc.
טיפול בפריטים שנמחקו
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);
הגדרת מטא-נתונים ויצירת הפריט
GraphTraversalSample.java
// Url is required. Use google.com as a placeholder for this sample.
String viewUrl = "https://www.google.com";

// Version is required, set to current timestamp.
byte[] version = Longs.toByteArray(System.currentTimeMillis());

// Using the SDK item builder class to create the document with
// appropriate attributes. This can be expanded to include metadata
// fields etc.
Item item = IndexingItemBuilder.fromConfiguration(documentId)
    .setItemType(IndexingItemBuilder.ItemType.CONTENT_ITEM)
    .setAcl(acl)
    .setSourceRepositoryUrl(IndexingItemBuilder.FieldOrValue.withValue(viewUrl))
    .setVersion(version)
    .build();
GraphTraversalSample.java
// For this sample, content is just plain text
String content = String.format("Hello world from sample doc %s", documentId);
ByteArrayContent byteContent = ByteArrayContent.fromString("text/plain", content);

RepositoryDoc.Builder docBuilder = new RepositoryDoc.Builder()
    .setItem(item)
    .setContent(byteContent, IndexingService.ContentFormat.TEXT);
הוספת מזהי צאצא לתור של יצירת האינדקס
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();

יצירת מחבר תוכן באמצעות API ל-REST

בקטעים הבאים מוסבר איך ליצור מחבר תוכן באמצעות ה-API ל-REST.

קביעת אסטרטגיית המעבר

האסטרטגיות (מלאה, רשימה וגרף) זהות מבחינה רעיונית לאסטרטגיות של ה-SDK. מטמיעים את האסטרטגיה שבחרתם באמצעות API ל-REST.

הטמעה של אסטרטגיית המעבר ופריטים לאינדקס

רושמים את הסכימה, ואז מאכלסים את האינדקס באמצעות:

  1. (אופציונלי) items.upload לקבצים שגדולים מ-100KiB.
  2. (אופציונלי) media.upload לקובצי מדיה.
  3. items.index כדי להוסיף את הפריט לאינדקס.

    דוגמה לבקשה להוספה לאינדקס:

    {
      "name": "datasource/<data_source_id>/items/titanic",
      "acl": {
        "readers": [
          {
            "gsuitePrincipal": {
              "gsuiteDomain": true
            }
          }
        ]
      },
      "metadata": {
        "title": "Titanic",
        "viewUrl": "http://www.imdb.com/title/tt2234155/",
        "objectType": "movie"
      },
      "structuredData": {
        "object": {
          "properties": [
            {
              "name": "movieTitle",
              "textValues": { "values": ["Titanic"] }
            }
          ]
        }
      },
      "content": {
        "inlineContent": "A seventeen-year-old aristocrat falls in love...",
        "contentFormat": "TEXT"
      },
      "version": "01",
      "itemType": "CONTENT_ITEM"
    }
    
  4. (אופציונלי) משתמשים בitems.get כדי לאמת את ההוספה לאינדקס.

טיפול בשינויים במאגר

כדי לבצע אינדוקס מלא, צריך ליצור מחדש את האינדקס של כל המאגר באופן תקופתי. כדי לעבור על רשימה או על גרף, משתמשים בתור האינדוקס של Google Cloud כדי לעקוב אחרי שינויים ולאנדקס רק את מה שהשתנה. משתמשים ב-items.push כדי להוסיף פריטים לתור.