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

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

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

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

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

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

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

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

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

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

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'

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

הצגת רשימה של אסטרטגיית מעבר

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

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

מעבר בתרשים

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

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

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

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

הקטע הזה במסמכים מתייחס לקטעי קוד מהדוגמה FullTraversalSample.

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

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

לפני שמפעילים את application.start(), צריך להשתמש במחלקה IndexingApplication.Builder כדי ליצור את התבנית FullTraversalConnector. האובייקט FullTraversalConnector מקבל אובייקט Repository עם השיטות שמטמיעים את השיטות שלו. קטע הקוד הבא מראה כיצד ליישם את השיטה 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();
}

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

  1. הפונקציה מפעילה את השיטה Configuation.isInitialized() כדי לוודא שה-Configuration לא אותחל.
  2. הפעלת אובייקט Configuration באמצעות זוגות המפתח/ערך ש-Google מספקת. כל צמד מפתח/ערך מאוחסן באובייקט ConfigValue בתוך האובייקט Configuration.

הטמעת הממשק Repository

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

  • השיטה init(). כדי להגדיר ולהפעיל מאגר נתונים כלשהו, משנים את השיטה init().

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

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

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

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

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

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

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

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

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

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

ביצוע מעבר מלא

שינוי getAllDocs() כדי לבצע מעבר מלא ולהוסיף את המאגר לאינדקס. השיטה getAllDocs() מקבלת נקודת ביקורת. נקודת הביקורת משמשת להמשך ההוספה לאינדקס של פריט מסוים במקרה שהתהליך יופסק. מבצעים את הפעולות הבאות ב-method getAllDocs() לכל פריט במאגר:

  1. מגדירים הרשאות.
  2. מגדירים את המטא-נתונים של הפריט שרוצים להוסיף לאינדקס.
  3. משלבים את המטא-נתונים ואת הפריט לרכיב RepositoryDoc אחד שאפשר להוסיף לאינדקס.
  4. מקרבים כל פריט שניתן להוסיף לאינדקס באיטרטור שמוחזר באמצעות method getAllDocs(). שים לב ש-getAllDocs() למעשה מחזיר CheckpointCloseableIterable, שהוא איטרציה של אובייקטים ApiOperation, כל אובייקט שמייצג בקשת API שבוצעה ב-RepositoryDoc, כמו הוספה לאינדקס.

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

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

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

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

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

הערה: ממשק ה-API לאינדקס ב-Cloud Search תומך ברשימות ACL של דומיין יחיד. הוא לא תומך ברשימות ACL של דומיינים שונים. משתמשים במחלקה Acl.Builder כדי להגדיר גישה לכל פריט באמצעות רשימת ACL. קטע הקוד הבא, שנלקח מדגימת המעבר המלאה, מאפשר לכל המשתמשים או ל"חשבונות משתמשים" (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 עבור המאגר. לדוגמה, יכול להיות שאתם מוסיפים קבצים לאינדקס בתוך מערכת קבצים שמשתמשת במודל ירושה כלשהו שבו תיקיות צאצא מקבלות הרשאות מתיקיות הורה. כדי ליצור מודלים לירושה של רשימות ACL, נדרש מידע נוסף שמכוסה ברשימות ACL של Google Cloud Search

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

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

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

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

ארזו כל פריט שניתן להוספה לאינדקס באיטרטור

השיטה getAllDocs() מחזירה Iterator, באופן ספציפי CheckpointCloseableIterable, של אובייקטים RepositoryDoc. אפשר להשתמש במחלקה CheckpointClosableIterableImpl.Builder כדי ליצור ולהחזיר איטרטור. קטע הקוד הבא מראה איך ליצור ולהחזיר איטרטור.

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

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

השלבים הבאים

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

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

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

הקטע הזה במסמכים מתייחס לקטעי קוד מהדוגמה ListTraversalSample.

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

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

לפני שמפעילים את application.start(), צריך להשתמש במחלקה IndexingApplication.Builder כדי ליצור את התבנית ListingConnector. ListingConnector מקבל אובייקט Repository שאת השיטות שלו מטמיעים. קטע הקוד הבא מראה איך ליצור את ListingConnector ואת ה-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();
}

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

  1. הפונקציה מפעילה את השיטה Configuation.isInitialized() כדי לוודא שה-Configuration לא אותחל.
  2. הפעלת אובייקט Configuration באמצעות זוגות המפתח/ערך ש-Google מספקת. כל צמד מפתח/ערך מאוחסן באובייקט ConfigValue בתוך האובייקט Configuration.

הטמעת הממשק Repository

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

  • השיטה init(). כדי להגדיר ולהפעיל מאגר נתונים כלשהו, משנים את השיטה init().

  • השיטה getIds(). על מנת לאחזר מזהים וערכי גיבוב לכל הרשומות במאגר, צריך לבטל את השיטה getIds().

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

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

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

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

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

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

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

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

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

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

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

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

בשלב הבא, משנים את השיטה getDoc() כדי לטפל בכל פריט בתור ההוספה לאינדקס ב-Cloud Search.

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

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

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

  • קבלו מהמאגר כל מזהה פריט וערך גיבוב (hash) המשויך אליו.
  • אורזים כל צמד של מזהה וערך גיבוב ב-PushItems.
  • משלבים כל PushItems באיטרטור שמוחזר באמצעות השיטה getIds(). שים לב ש-getIds() מחזיר למעשה CheckpointCloseableIterable, שהוא איטרציה של אובייקטים ApiOperation, כל אובייקט שמייצג בקשת API שבוצעה ב-RepositoryDoc, כמו דחיפת הפריטים לתור.

קטע הקוד הבא מראה איך לקבל כל מזהה פריט וערך גיבוב (hash) ולהכניס אותם ל-PushItems. PushItems היא בקשה של ApiOperation לדחוף פריט לתור ההוספה לאינדקס של 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);
}

קטע הקוד הבא מראה איך להשתמש במחלקה PushItems.Builder כדי לארוז את המזהים ואת ערכי הגיבוב (hash) בדחיפה אחת של ApiOperation.

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

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

אחזר כל פריט וטפל בו

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

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

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

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

  3. אינדקס השתנה או פריטים חדשים:

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

הערה: התבנית ListingConnector לא תומכת בהחזרת null בשיטה getDoc(). החזרת null תוצאות בNullPointerException.

טיפול בפריטים שנמחקו

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

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

שימו לב ש-documents הוא מבנה נתונים שמייצג את המאגר. אם documentID לא נמצא ב-documents, חוזרים APIOperations.deleteItem(resourceName) כדי למחוק את הפריט מהאינדקס.

טיפול בפריטים שלא השתנו

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

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 יהיה את המידע הנדרש כדי לקבל את רמת הגישה המתאימה לפריט.

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

הערה: ממשק ה-API לאינדקס ב-Cloud Search תומך ברשימות ACL של דומיין יחיד. הוא לא תומך ברשימות ACL של דומיינים שונים. משתמשים במחלקה Acl.Builder כדי להגדיר גישה לכל פריט באמצעות רשימת ACL. קטע הקוד הבא, שנלקח מדגימת המעבר המלאה, מאפשר לכל המשתמשים או ל"חשבונות משתמשים" (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 עבור המאגר. לדוגמה, יכול להיות שאתם מוסיפים קבצים לאינדקס בתוך מערכת קבצים שמשתמשת במודל ירושה כלשהו שבו תיקיות צאצא מקבלות הרשאות מתיקיות הורה. כדי ליצור מודלים לירושה של רשימות ACL, נדרש מידע נוסף שמכוסה ברשימות ACL של Google Cloud Search

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

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

יצירת פריט שניתן להוסיף לאינדקס

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

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 הוא סוג של ApiOperation שמבצע את הבקשה IndexingService.indexItem() בפועל.

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

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

השלבים הבאים

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

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

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

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

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

הקטע הזה במסמכים מתייחס לקטעי קוד מהדוגמה GraphTraversalSample.

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

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

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

קטע הקוד הבא מראה איך ליצור את ListingConnector ואת ה-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();
}

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

  1. הפונקציה מפעילה את השיטה Configuation.isInitialized() כדי לוודא שה-Configuration לא אותחל.
  2. הפעלת אובייקט Configuration באמצעות זוגות המפתח/ערך ש-Google מספקת. כל צמד מפתח/ערך מאוחסן באובייקט ConfigValue בתוך האובייקט Configuration.

הטמעת הממשק Repository

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

  • השיטה init(). כדי להגדיר ולהפעיל מאגר נתונים כלשהו, משנים את השיטה init().

  • השיטה getIds(). על מנת לאחזר מזהים וערכי גיבוב לכל הרשומות במאגר, צריך לבטל את השיטה getIds().

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

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

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

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

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

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

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

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

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

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

בצעו את המעבר בין הגרף

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

בשלב הבא, משנים את השיטה getDoc() כדי לטפל בכל פריט בתור ההוספה לאינדקס ב-Cloud Search.

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

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

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

  • קבלו מהמאגר כל מזהה פריט וערך גיבוב (hash) המשויך אליו.
  • אורזים כל צמד של מזהה וערך גיבוב ב-PushItems.
  • משלבים כל PushItems באיטרטור שמוחזר באמצעות השיטה getIds(). שים לב ש-getIds() מחזיר למעשה CheckpointCloseableIterable, שהוא איטרציה של אובייקטים ApiOperation, כל אובייקט שמייצג בקשת API שבוצעה ב-RepositoryDoc, כמו דחיפת הפריטים לתור.

קטע הקוד הבא מראה איך לקבל כל מזהה פריט וערך גיבוב (hash) ולהכניס אותם ל-PushItems. PushItems היא בקשה ApiOperation לדחיפה של פריט לתור ההוספה לאינדקס ב-Cloud Search.

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

קטע הקוד הבא מראה איך להשתמש במחלקה PushItems.Builder כדי לארוז את המזהים ואת ערכי הגיבוב (hash) בדחיפה אחת של ApiOperation.

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

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

אחזר כל פריט וטפל בו

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

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

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

  2. אינדקס השתנה או פריטים חדשים:

    1. מגדירים את ההרשאות.
    2. מגדירים את המטא-נתונים של הפריט שרוצים להוסיף לאינדקס.
    3. משלבים את המטא-נתונים ואת הפריט לרכיב RepositoryDoc אחד שאפשר להוסיף לאינדקס.
    4. צריך להוסיף את מזהי הצאצאים לתור ההוספה לאינדקס ב-Cloud Search לצורך עיבוד נוסף.
    5. מחזירים את הערך 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);

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

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

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

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

הערה: ממשק ה-API לאינדקס ב-Cloud Search תומך ברשימות ACL של דומיין יחיד. הוא לא תומך ברשימות ACL של דומיינים שונים. משתמשים במחלקה Acl.Builder כדי להגדיר גישה לכל פריט באמצעות רשימת ACL. קטע הקוד הבא, שנלקח מדגימת המעבר המלאה, מאפשר לכל המשתמשים או ל"חשבונות משתמשים" (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 עבור המאגר. לדוגמה, יכול להיות שאתם מוסיפים קבצים לאינדקס בתוך מערכת קבצים שמשתמשת במודל ירושה כלשהו שבו תיקיות צאצא מקבלות הרשאות מתיקיות הורה. כדי ליצור מודלים לירושה של רשימות ACL, נדרש מידע נוסף שמכוסה ברשימות ACL של Google Cloud Search

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

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

יצירת הפריט שאפשר להוסיף לאינדקס

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

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 הוא סוג של ApiOperation שמבצע את בקשת IndexingService.indexItem() בפועל.

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

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

הוספה של מזהי הצאצאים לתור ההוספה לאינדקס ב-Cloud Search

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

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

השלבים הבאים

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

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

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

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

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

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

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

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

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

הצגת רשימה של אסטרטגיית מעבר

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

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

מעבר בתרשים

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

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

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

כל רכיב שאפשר להוסיף לאינדקס ב-Cloud Search נקרא פריט ב-Cloud Search API. פריט יכול להיות קובץ, תיקייה, שורה בקובץ CSV או רשומת מסד נתונים.

אחרי רישום הסכימה, אפשר לאכלס את האינדקס על ידי:

  1. (אופציונלי) שימוש ב-items.upload להעלאת קבצים שגדולים מ-100KiB להוספה לאינדקס. בקבצים קטנים יותר, אפשר להטמיע את התוכן כ-inlineContent באמצעות items.index.

  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/?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. (אופציונלי) שימוש בקריאות ל-items.get כדי לאמת שפריט נוסף לאינדקס.

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

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

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

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

מידע נוסף על Google Cloud Search API זמין במאמר Cloud Search API.