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

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

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

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

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

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

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

בקטעים הבאים מוסבר איך ליצור מחבר תוכן באמצעות Content Connector 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.

ב-Google Cloud Search SDK יש כמה הגדרות ש-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() אחרי הפעלת ה-method 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 לאובייקט. משימה זו מתבצעת בדרך כלל Repository של הכיתה init().

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

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

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

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

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

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

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

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

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

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

השלבים הבאים

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

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

התור של ההוספה לאינדקס של Cloud Search משמש להחזקה של מזהים וגיבוב אופציונלי לכל פריט במאגר. מחבר מעבר ברשימה דוחף מזהי פריטים בתור ההוספה לאינדקס של 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() אחרי הפעלת ה-method main() של המחבר Application.build. השיטה initConfig():

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

הטמעת הממשק של Repository

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 יכולה להיות מסובכת. למידע נוסף ב-Google רשימות ACL של Cloud Search, מופיעות במאמר רשימות ACL של Google Cloud Search.

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

השלבים הבאים

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

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

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

התור של ההוספה לאינדקס ב-Cloud Search משמש להחזקה של מזהים וערכי גיבוב (hash) אופציונליים לכל פריט במאגר. מחבר מעבר תרשים שדוחף את מזהי הפריטים אל תור ההוספה לאינדקס של 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() אחרי הפעלת ה-method main() של המחבר Application.build. השיטה initConfig():

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

הטמעת הממשק של Repository

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ה-method getDoc() מקבלת פריט מ-Cloud Search Indexing הבאים בתור. עבור כל פריט בתור, מבצעים את השלבים הבאים אמצעי תשלום אחד (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 יכולה להיות מסובכת. למידע נוסף ב-Google רשימות ACL של Cloud Search, מופיעות במאמר רשימות ACL של Google Cloud Search.

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

יצירה של מחבר תוכן באמצעות 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 כמנגנון למעקב אחר שינויים ולהוספה לאינדקס רק של פריטים השתנה. אפשר להשתמש items.push בקשות להעביר פריטים לתור לקלפיות ולעדכון מאוחר יותר. לקבלת מידע נוסף על התור ליצירת אינדקס ב-Google Cloud, תור ההוספה לאינדקס של Google Cloud.

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