إنشاء موصِّل محتوى

موصّل المحتوى هو برنامج يُستخدَم لتصفّح البيانات في مستودع إحدى المؤسسات وتعبئة مصدر بيانات. توفّر Google الخيارات التالية لتطوير أدوات ربط المحتوى:

  • حزمة تطوير البرامج (SDK) الخاصة بموصل المحتوى يُعدّ هذا الخيار مناسبًا إذا كنت تبرمج بلغة Java. حزمة تطوير البرامج (SDK) الخاصة بـ Content Connector هي برنامج تضمين لواجهة REST API، ما يتيح لك إنشاء موصّلات بسرعة. لإنشاء موصّل محتوى باستخدام حزمة تطوير البرامج (SDK)، يُرجى الرجوع إلى إنشاء موصّل محتوى باستخدام Content Connector SDK.

  • واجهة برمجة تطبيقات REST منخفضة المستوى أو مكتبات واجهة برمجة التطبيقات استخدِم هذه الخيارات إذا كنت لا تبرمج بلغة Java، أو إذا كان رمزك الأساسي يتوافق بشكل أفضل مع واجهة برمجة تطبيقات REST أو مكتبة. لإنشاء موصّل محتوى باستخدام REST API، يُرجى الاطّلاع على مقالة إنشاء موصّل محتوى باستخدام REST API.

يُجري موصّل المحتوى النموذجي المهام التالية:

  1. تقرأ هذه السمة مَعلمات الإعداد وتعالجها.
  2. يستخرج هذا الموصل أجزاء منفصلة من البيانات القابلة للفهرسة، تُعرف باسم "العناصر"، من مستودع المحتوى التابع للجهة الخارجية.
  3. يجمع بين قوائم التحكّم بالوصول والبيانات الوصفية وبيانات المحتوى في عناصر قابلة للفهرسة.
  4. يفهرس العناصر في مصدر بيانات Cloud Search.
  5. (اختياري) يستمع إلى إشعارات التغيير من مستودع المحتوى التابع لجهة خارجية. يتم تحويل الإشعارات بالتغييرات إلى طلبات فهرسة للحفاظ على مزامنة مصدر البيانات في Cloud Search مع المستودع التابع لجهة خارجية. لا ينفّذ الموصل هذه المهمة إلا إذا كان المستودع يتيح رصد التغييرات.

إنشاء موصّل محتوى باستخدام Content Connector SDK

توضّح الأقسام التالية كيفية إنشاء أداة ربط محتوى باستخدام حزمة تطوير البرامج (SDK) الخاصة بأداة ربط المحتوى.

إعداد التبعيات

يجب تضمين بعض الملحقات في ملف الإنشاء لاستخدام حزمة SDK. انقر على إحدى علامات التبويب أدناه لعرض التبعيات الخاصة ببيئة الإصدار:

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'

إنشاء إعدادات الموصّل

يحتوي كل موصّل على ملف إعداد يتضمّن مَعلمات يستخدمها الموصّل، مثل رقم تعريف المستودع. يتم تعريف المَعلمات على أنّها أزواج مفتاح-قيمة، مثل 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. يتم تنفيذ هذه المهمة عادةً في طريقة Repository ضمن فئة init().

يحتوي الصف Configuration على عدة طرق للحصول على أنواع مختلفة من البيانات من الإعدادات. تعرض كل طريقة كائن ConfigValue. بعد ذلك، ستستخدم طريقة get() الخاصة بالكائن ConfigValue لاسترداد القيمة الفعلية. يوضّح المقتطف التالي، المأخوذ من 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() نقطة تحقّق. يتم استخدام نقطة التحقّق لاستئناف الفهرسة عند عنصر معيّن في حال انقطاع العملية. بالنسبة إلى كل عنصر في المستودع، اتّبِع الخطوات التالية في طريقة getAllDocs():

  1. تحديد الأذونات
  2. اضبط البيانات الوصفية للعنصر الذي تريد فهرسته.
  3. اجمع البيانات الوصفية والعنصر في RepositoryDoc واحد قابل للفهرسة.
  4. يجب تجميع كل عنصر قابل للفهرسة في مكرّر تعرضه الطريقة getAllDocs(). يُرجى العِلم أنّ getAllDocs() تعرض في الواقع CheckpointCloseableIterable وهي تكرار ApiOperation للكائنات، ويمثّل كل كائن طلبًا من واجهة برمجة التطبيقات تم تنفيذه على RepositoryDoc، مثل فهرسته.

إذا كانت مجموعة العناصر كبيرة جدًا بحيث يتعذّر معالجتها في طلب واحد، أدرِج نقطة تحقّق واضبط hasMore(true) للإشارة إلى توفّر المزيد من العناصر للفهرسة.

ضبط الأذونات لعنصر

يستخدم المستودع قائمة التحكّم بالوصول (ACL) لتحديد المستخدمين أو المجموعات الذين يمكنهم الوصول إلى عنصر معيّن. قائمة التحكم في الوصول هي قائمة تتضمّن معرّفات المجموعات أو المستخدمين الذين يمكنهم الوصول إلى العنصر.

يجب تكرار قائمة التحكّم بالوصول (ACL) المستخدَمة في المستودع لضمان أنّ المستخدمين الذين يمكنهم الوصول إلى عنصر معيّن هم فقط من يمكنهم رؤية هذا العنصر ضمن نتيجة البحث. يجب تضمين قائمة التحكّم بالوصول (ACL) الخاصة بأحد العناصر عند فهرسته لكي تتوفر لدى Google Cloud Search المعلومات اللازمة لتوفير مستوى الوصول الصحيح إلى العنصر.

توفّر حزمة تطوير البرامج (SDK) الخاصة بأداة ربط المحتوى مجموعة كبيرة من فئات وقواعد بيانات قوائم التحكّم بالوصول (ACL) لتصميم قوائم التحكّم بالوصول لمعظم المستودعات. عليك تحليل قائمة التحكّم بالوصول لكل عنصر في المستودع وإنشاء قائمة تحكّم بالوصول مقابلة في Google Cloud Search عند فهرسة عنصر. إذا كانت قائمة التحكّم بالوصول (ACL) في مستودعك تستخدم مفاهيم مثل توريث قائمة التحكّم بالوصول، قد يكون من الصعب تصميم قائمة التحكّم بالوصول هذه. لمزيد من المعلومات حول قوائم التحكّم بالوصول في Google Cloud Search، يُرجى الرجوع إلى مقالة قوائم التحكّم بالوصول في Google Cloud Search.

ملاحظة: تتيح واجهة برمجة التطبيقات الخاصة بالفهرسة في Cloud Search قوائم التحكّم بالوصول (ACL) ذات النطاق الواحد. ولا تتوافق مع قوائم التحكم بالوصول عبر النطاقات. استخدِم الفئة 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();

عليك فهم قوائم التحكم بالوصول لتتمكّن من تصميمها بشكل صحيح للمستودع. على سبيل المثال، قد تفهرس ملفات ضمن نظام ملفات يستخدم نوعًا من نموذج التوريث حيث تكتسب المجلدات الفرعية الأذونات من المجلدات الرئيسية. تتطلّب نمذجة وراثة قوائم التحكّم بالوصول معلومات إضافية موضّحة في قوائم التحكّم بالوصول في Google Cloud Search

ضبط البيانات الوصفية لعنصر

يتم تخزين البيانات الوصفية في عنصر Item. لإنشاء Item، يجب توفير الحد الأدنى من البيانات، وهي معرّف سلسلة فريد ونوع العنصر وقائمة التحكّم بالوصول وعنوان 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();

تنفّذ حزمة تطوير البرامج كل طلب فهرسة مضمّن في المكرّر.

الخطوات التالية

في ما يلي بعض الخطوات التالية التي يمكنك اتّخاذها:

إنشاء أداة ربط لتصفّح القوائم باستخدام فئة نموذج

يتم استخدام قائمة انتظار الفهرسة في 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() بعد أن تستدعي طريقة 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. يتم تنفيذ هذه المهمة عادةً في طريقة Repository ضمن فئة init().

يحتوي الصف Configuration على عدة طرق للحصول على أنواع مختلفة من البيانات من الإعدادات. تعرض كل طريقة كائن ConfigValue. بعد ذلك، ستستخدم طريقة get() الخاصة بالكائن ConfigValue لاسترداد القيمة الفعلية. يوضّح المقتطف التالي، المأخوذ من 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() الطريقة لاسترداد المعرّفات وقيم التجزئة لجميع السجلات في المستودع. تقبل طريقة getIds() نقطة تحقّق. يتم استخدام نقطة التحقّق لاستئناف الفهرسة عند عنصر معيّن في حال انقطاع العملية.

بعد ذلك، عليك تجاهل طريقة getDoc() للتعامل مع كل عنصر في قائمة انتظار الفهرسة في Cloud Search.

إرسال معرّفات السلع وقيم التجزئة

Override getIds() لجلب أرقام تعريف العناصر وقيم تجزئة المحتوى المرتبطة بها من المستودع. يتم بعد ذلك تجميع أزواج أرقام التعريف وقيم التجزئة في طلب عملية إرسال إلى قائمة انتظار الفهرسة في Cloud Search. يتم عادةً إرسال أرقام التعريف الجذرية أو الرئيسية أولاً، ثم أرقام تعريف العناصر الفرعية إلى أن تتم معالجة التسلسل الهرمي الكامل للعناصر.

تقبل الطريقة getIds() نقطة تحقّق تمثّل العنصر الأخير الذي سيتم فهرسته. يمكن استخدام نقطة التحقّق لاستئناف الفهرسة عند عنصر معيّن في حال انقطاع العملية. بالنسبة إلى كل عنصر في المستودع، اتّبِع الخطوات التالية في طريقة getIds():

  • احصل على معرّف كل عنصر وقيمة التجزئة المرتبطة به من المستودع.
  • ضمِّن كل زوج من رقم التعريف وقيمة التجزئة في PushItems.
  • اجمع كل PushItems في مكرّر يعرضه الطريقة getIds(). يُرجى العِلم أنّ getIds() تعرض في الواقع CheckpointCloseableIterable وهي تكرار ApiOperation للكائنات، ويمثّل كل كائن طلبًا من واجهة برمجة التطبيقات تم تنفيذه على RepositoryDoc ، مثل إضافة العناصر إلى قائمة الانتظار.

يوضّح مقتطف الرمز البرمجي التالي كيفية الحصول على معرّف كل عنصر وقيمة التجزئة وإدراجهما في 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();
}

لتحديد ما إذا كان العنصر لم يتم تعديله، تحقَّق من حالة العنصر بالإضافة إلى البيانات الوصفية الأخرى التي قد تشير إلى حدوث تغيير. في المثال، يتم استخدام تجزئة البيانات الوصفية لتحديد ما إذا تم تغيير العنصر.

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) الخاصة بأحد العناصر عند فهرسته لكي تتوفر لدى Google Cloud Search المعلومات اللازمة لتوفير مستوى الوصول الصحيح إلى العنصر.

توفّر حزمة تطوير البرامج (SDK) الخاصة بأداة ربط المحتوى مجموعة كبيرة من فئات وقواعد بيانات قوائم التحكّم بالوصول (ACL) لتصميم قوائم التحكّم بالوصول لمعظم المستودعات. عليك تحليل قائمة التحكّم بالوصول لكل عنصر في المستودع وإنشاء قائمة تحكّم بالوصول مقابلة في Google Cloud Search عند فهرسة عنصر. إذا كانت قائمة التحكّم بالوصول (ACL) في مستودعك تستخدم مفاهيم مثل توريث قائمة التحكّم بالوصول، قد يكون من الصعب تصميم قائمة التحكّم بالوصول هذه. لمزيد من المعلومات حول قوائم التحكّم بالوصول في Google Cloud Search، يُرجى الرجوع إلى مقالة قوائم التحكّم بالوصول في Google Cloud Search.

ملاحظة: تتيح واجهة برمجة التطبيقات الخاصة بالفهرسة في Cloud Search قوائم التحكّم بالوصول (ACL) ذات النطاق الواحد. ولا تتوافق مع قوائم التحكم بالوصول عبر النطاقات. استخدِم الفئة 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();

عليك فهم قوائم التحكم بالوصول لتتمكّن من تصميمها بشكل صحيح للمستودع. على سبيل المثال، قد تفهرس ملفات ضمن نظام ملفات يستخدم نوعًا من نموذج التوريث حيث تكتسب المجلدات الفرعية الأذونات من المجلدات الرئيسية. تتطلّب نمذجة وراثة قوائم التحكّم بالوصول معلومات إضافية موضّحة في قوائم التحكّم بالوصول في Google Cloud Search

ضبط البيانات الوصفية لعنصر

يتم تخزين البيانات الوصفية في عنصر Item. لإنشاء Item، يجب توفير الحد الأدنى من البيانات، وهي معرّف سلسلة فريد ونوع العنصر وقائمة التحكّم بالوصول وعنوان 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() لتحرير أي موارد قبل الإيقاف.
  • (اختياري) إنشاء موصّل هوية باستخدام Content Connector 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. يتم تنفيذ هذه المهمة عادةً في طريقة Repository ضمن فئة init().

يحتوي الصف Configuration على عدة طرق للحصول على أنواع مختلفة من البيانات من الإعدادات. تعرض كل طريقة كائن ConfigValue. بعد ذلك، ستستخدم طريقة get() الخاصة بالكائن ConfigValue لاسترداد القيمة الفعلية. يوضّح المقتطف التالي، المأخوذ من 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() الطريقة لاسترداد المعرّفات وقيم التجزئة لجميع السجلات في المستودع. تقبل طريقة getIds() نقطة تحقّق. يتم استخدام نقطة التحقّق لاستئناف الفهرسة عند عنصر معيّن في حال انقطاع العملية.

بعد ذلك، عليك تجاهل طريقة getDoc() للتعامل مع كل عنصر في قائمة انتظار الفهرسة في Cloud Search.

إرسال معرّفات السلع وقيم التجزئة

Override getIds() لجلب أرقام تعريف العناصر وقيم تجزئة المحتوى المرتبطة بها من المستودع. يتم بعد ذلك تجميع أزواج أرقام التعريف وقيم التجزئة في طلب عملية إرسال إلى قائمة انتظار الفهرسة في Cloud Search. يتم عادةً إرسال أرقام التعريف الجذرية أو الرئيسية أولاً، ثم أرقام تعريف العناصر الفرعية إلى أن تتم معالجة التسلسل الهرمي الكامل للعناصر.

تقبل الطريقة getIds() نقطة تحقّق تمثّل العنصر الأخير الذي سيتم فهرسته. يمكن استخدام نقطة التحقّق لاستئناف الفهرسة عند عنصر معيّن في حال انقطاع العملية. بالنسبة إلى كل عنصر في المستودع، اتّبِع الخطوات التالية في طريقة getIds():

  • احصل على معرّف كل عنصر وقيمة التجزئة المرتبطة به من المستودع.
  • ضمِّن كل زوج من رقم التعريف وقيمة التجزئة في PushItems.
  • اجمع كل PushItems في مكرّر يعرضه الطريقة getIds(). يُرجى العِلم أنّ getIds() تعرض في الواقع CheckpointCloseableIterable وهي تكرار ApiOperation للكائنات، ويمثّل كل كائن طلبًا من واجهة برمجة التطبيقات تم تنفيذه على RepositoryDoc ، مثل إضافة العناصر إلى قائمة الانتظار.

يوضّح مقتطف الرمز البرمجي التالي كيفية الحصول على معرّف كل عنصر وقيمة التجزئة وإدراجهما في 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. يمكن أن يكون العنصر جديدًا أو معدَّلاً أو بدون تغيير أو لم يعُد متوفّرًا في مستودع المصدر. استرداد وفهرسة كل عنصر جديد أو معدَّل إزالة العناصر من الفهرس التي لم تعُد متوفّرة في مستودع المصدر

تقبل الطريقة 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) الخاصة بأحد العناصر عند فهرسته لكي تتوفر لدى Google Cloud Search المعلومات اللازمة لتوفير مستوى الوصول الصحيح إلى العنصر.

توفّر حزمة تطوير البرامج (SDK) الخاصة بأداة ربط المحتوى مجموعة كبيرة من فئات وقواعد بيانات قوائم التحكّم بالوصول (ACL) لتصميم قوائم التحكّم بالوصول لمعظم المستودعات. عليك تحليل قائمة التحكّم بالوصول لكل عنصر في المستودع وإنشاء قائمة تحكّم بالوصول مقابلة في Google Cloud Search عند فهرسة عنصر. إذا كانت قائمة التحكّم بالوصول (ACL) في مستودعك تستخدم مفاهيم مثل توريث قائمة التحكّم بالوصول، قد يكون من الصعب تصميم قائمة التحكّم بالوصول هذه. لمزيد من المعلومات حول قوائم التحكّم بالوصول في Google Cloud Search، يُرجى الرجوع إلى مقالة قوائم التحكّم بالوصول في Google Cloud Search.

ملاحظة: تتيح واجهة برمجة التطبيقات الخاصة بالفهرسة في Cloud Search قوائم التحكّم بالوصول (ACL) ذات النطاق الواحد. ولا تتوافق مع قوائم التحكم بالوصول عبر النطاقات. استخدِم الفئة 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();

عليك فهم قوائم التحكم بالوصول لتتمكّن من تصميمها بشكل صحيح للمستودع. على سبيل المثال، قد تفهرس ملفات ضمن نظام ملفات يستخدم نوعًا من نموذج التوريث حيث تكتسب المجلدات الفرعية الأذونات من المجلدات الرئيسية. تتطلّب نمذجة وراثة قوائم التحكّم بالوصول معلومات إضافية موضّحة في قوائم التحكّم بالوصول في Google Cloud Search

ضبط البيانات الوصفية لعنصر

يتم تخزين البيانات الوصفية في عنصر Item. لإنشاء Item، يجب توفير الحد الأدنى من البيانات، وهي معرّف سلسلة فريد ونوع العنصر وقائمة التحكّم بالوصول وعنوان 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() لتحرير أي موارد قبل الإيقاف.
  • (اختياري) إنشاء موصّل هوية باستخدام Identity Connector SDK

إنشاء موصّل محتوى باستخدام REST API

توضّح الأقسام التالية كيفية إنشاء أداة ربط محتوى باستخدام واجهة REST API.

تحديد استراتيجية التنقّل

تتمثّل الوظيفة الأساسية لأداة ربط المحتوى في استكشاف مستودع وفهرسة بياناته. يجب تنفيذ استراتيجية اجتياز استنادًا إلى حجم البيانات وتصميمها في المستودع. في ما يلي ثلاث استراتيجيات شائعة للتنقّل:

استراتيجية التنقّل الكامل

تتضمّن استراتيجية البحث الشامل فحص المستودع بأكمله وفهرسة كل عنصر بدون تمييز. تُستخدَم هذه الاستراتيجية عادةً عندما يكون لديك مستودع صغير ويمكنك تحمّل تكلفة إجراء بحث كامل في كل مرة تتم فيها الفهرسة.

تكون استراتيجية الاجتياز هذه مناسبة للمستودعات الصغيرة التي تحتوي على بيانات ثابتة وغير هرمية في الغالب. يمكنك أيضًا استخدام استراتيجية التنقّل هذه عندما يكون رصد التغييرات صعبًا أو غير متاح في المستودع.

استراتيجية التنقّل في القائمة

تفحص استراتيجية اجتياز القائمة المستودع بأكمله، بما في ذلك جميع العُقد الفرعية، لتحديد حالة كل عنصر. بعد ذلك، ينفّذ الموصّل عملية فحص ثانية ولا يفهرس سوى العناصر الجديدة أو التي تم تعديلها منذ آخر عملية فهرسة. تُستخدَم هذه الاستراتيجية عادةً لإجراء تعديلات إضافية على فهرس حالي (بدلاً من إجراء عملية بحث كاملة في كل مرة تعدّل فيها الفهرس).

تكون استراتيجية الانتقال هذه مناسبة عندما يكون من الصعب رصد التغييرات أو عندما لا يتيح المستودع رصدها، وعندما تكون لديك بيانات غير هرمية، وعندما تعمل مع مجموعات بيانات كبيرة جدًا.

اجتياز الرسم البياني

تفحص استراتيجية اجتياز الرسم البياني العقدة الرئيسية بأكملها لتحديد حالة كل عنصر. بعد ذلك، يجري الموصّل عملية فحص ثانية ولا يفهرس سوى العناصر الجديدة أو التي تم تعديلها منذ آخر عملية فهرسة في عقدة الجذر. أخيرًا، يمرِّر الموصل أي أرقام تعريف للعناصر الثانوية ثم يفهرس العناصر في العُقد الثانوية التي تم إنشاؤها حديثًا أو تعديلها. يواصل الموصل التنفيذ بشكل متكرر من خلال جميع العُقد الفرعية إلى أن يتم تناول جميع العناصر. ويُستخدم هذا النوع من الاجتياز عادةً للمستودعات الهرمية التي لا يكون فيها إدراج جميع المعرّفات أمرًا عمليًا.

تكون هذه الاستراتيجية مناسبة إذا كانت لديك بيانات هرمية يجب الزحف إليها، مثل سلسلة من الدلائل أو صفحات الويب.

تنفيذ استراتيجية الانتقال وفهرسة العناصر

يُشار إلى كل عنصر قابل للفهرسة في Cloud Search باسم عنصر في Cloud Search API. قد يكون العنصر ملفًا أو مجلدًا أو سطرًا في ملف CSV أو سجل قاعدة بيانات.

بعد تسجيل المخطط، يمكنك ملء الفهرس من خلال:

  1. (اختياري) استخدام items.upload لتحميل ملفات أكبر من 100 كيلوبايت بغرض الفهرسة بالنسبة إلى الملفات الأصغر حجمًا، يمكنك تضمين المحتوى كـ 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.