یک اتصال دهنده محتوا ایجاد کنید

رابط محتوا یک برنامه نرم افزاری است که برای پیمایش داده ها در مخزن یک سازمان و پر کردن منبع داده استفاده می شود. گوگل گزینه های زیر را برای توسعه اتصال دهنده های محتوا ارائه می دهد:

  • Content Connector SDK. اگر به زبان جاوا برنامه نویسی می کنید این گزینه خوبی است. Content Connector SDK یک بسته بندی در اطراف REST API است که به شما امکان می دهد به سرعت اتصالات ایجاد کنید. برای ایجاد یک رابط محتوا با استفاده از SDK، به ایجاد رابط محتوا با استفاده از Content Connector SDK مراجعه کنید.

  • یک REST API یا کتابخانه های API سطح پایین. اگر در جاوا برنامه نویسی نمی کنید، یا اگر پایگاه کد شما بهتر از یک REST API یا یک کتابخانه استفاده می کند، از این گزینه ها استفاده کنید. برای ایجاد یک رابط محتوا با استفاده از REST API، به ایجاد رابط محتوا با استفاده از REST API مراجعه کنید.

یک اتصال دهنده محتوای معمولی وظایف زیر را انجام می دهد:

  1. پارامترهای پیکربندی را می خواند و پردازش می کند.
  2. تکه های گسسته ای از داده های قابل نمایه سازی، به نام " اقلام " را از مخزن محتوای شخص ثالث می کشد.
  3. ACL ها، ابرداده ها و داده های محتوا را در آیتم های قابل نمایه سازی ترکیب می کند.
  4. موارد را به منبع داده Cloud Search فهرست می کند.
  5. (اختیاری) به تغییر اعلان‌ها از مخزن محتوای شخص ثالث گوش می‌دهد. اعلان‌های تغییر به درخواست‌های نمایه‌سازی تبدیل می‌شوند تا منبع داده Cloud Search با مخزن شخص ثالث همگام شود. کانکتور فقط در صورتی این کار را انجام می دهد که مخزن از تشخیص تغییر پشتیبانی کند.

با استفاده از Content Connector SDK یک رابط محتوا ایجاد کنید

بخش‌های زیر نحوه ایجاد یک رابط محتوا با استفاده از Content Connector SDK را توضیح می‌دهند.

وابستگی ها را تنظیم کنید

برای استفاده از SDK باید وابستگی های خاصی را در فایل ساخت خود قرار دهید. برای مشاهده وابستگی های محیط ساخت خود، روی یک تب زیر کلیک کنید:

ماون

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

گریدل

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

پیکربندی کانکتور خود را ایجاد کنید

هر کانکتور دارای یک فایل پیکربندی است که حاوی پارامترهایی است که توسط کانکتور استفاده می شود، مانند شناسه مخزن شما. پارامترها به عنوان جفت کلید-مقدار تعریف می شوند، مانند 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() را پس از فراخوانی متد main() کانکتور شما Application.build را فراخوانی می کند. متد initConfig() وظایف زیر را انجام می دهد:

  1. متد Configuation.isInitialized() را فراخوانی می کند تا مطمئن شود که Configuration اولیه نشده است.
  2. یک شی Configuration با جفت های کلید-مقدار ارائه شده توسط Google راه اندازی می کند. هر جفت کلید-مقدار در یک شی ConfigValue در شی Configuration ذخیره می شود.

رابط Repository را پیاده سازی کنید

تنها هدف شی Repository انجام پیمایش و نمایه سازی آیتم های مخزن است. هنگام استفاده از یک الگو، فقط باید روش‌های خاصی را در رابط Repository لغو کنید تا یک رابط محتوا ایجاد کنید. روش هایی که نادیده می گیرید به الگو و استراتژی پیمایشی که استفاده می کنید بستگی دارد. برای FullTraversalConnector ، روش‌های زیر را لغو کنید:

  • متد init() . برای انجام هرگونه راه اندازی و مقداردهی اولیه مخزن داده، روش init() را نادیده بگیرید.

  • متد getAllDocs() . برای پیمایش و فهرست کردن همه موارد موجود در مخزن داده، روش getAllDocs() را لغو کنید. این روش یک بار برای هر پیمایش زمانبندی شده (همانطور که توسط پیکربندی شما تعریف شده است) فراخوانی می شود.

  • (اختیاری) متد getChanges() . اگر مخزن شما از تشخیص تغییر پشتیبانی می کند، متد getChanges() را لغو کنید. این روش یک بار برای هر پیمایش افزایشی برنامه ریزی شده (همانطور که توسط پیکربندی شما تعریف شده است) فراخوانی می شود تا موارد اصلاح شده را بازیابی کرده و آنها را فهرست بندی کند.

  • (اختیاری) متد close() . اگر نیاز به پاکسازی مخزن دارید، متد close() لغو کنید. این روش یک بار در هنگام خاموش شدن کانکتور فراخوانی می شود.

هر یک از متدهای شی Repository نوعی از شیء ApiOperation را برمی گرداند. یک شیء ApiOperation عملی را به شکل یک یا شاید چند فراخوانی IndexingService.indexItem() انجام می دهد تا نمایه سازی واقعی مخزن شما را انجام دهد.

پارامترهای پیکربندی سفارشی را دریافت کنید

به عنوان بخشی از مدیریت پیکربندی کانکتور خود، باید هر پارامتر سفارشی را از شی Configuration دریافت کنید. این کار معمولاً در متد init() کلاس Repository انجام می شود.

کلاس Configuration چندین روش برای دریافت انواع داده های مختلف از یک پیکربندی دارد. هر متد یک شی ConfigValue را برمی گرداند. سپس از متد 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 است، که هر شی نشان دهنده یک درخواست API است که روی یک RepositoryDoc انجام می شود، مانند نمایه سازی آن.

اگر مجموعه موارد برای پردازش در یک تماس خیلی بزرگ است، یک نقطه بازرسی اضافه کنید و hasMore(true) را تنظیم کنید تا نشان دهید موارد بیشتری برای نمایه سازی در دسترس هستند.

مجوزها را برای یک مورد تنظیم کنید

مخزن شما از یک لیست کنترل دسترسی (ACL) برای شناسایی کاربران یا گروه هایی که به یک آیتم دسترسی دارند استفاده می کند. ACL لیستی از شناسه ها برای گروه ها یا کاربرانی است که می توانند به آیتم دسترسی داشته باشند.

شما باید ACL مورد استفاده توسط مخزن خود را کپی کنید تا مطمئن شوید فقط آن دسته از کاربرانی که به یک مورد دسترسی دارند می توانند آن مورد را در یک نتیجه جستجو ببینند. ACL برای یک مورد باید هنگام نمایه سازی یک مورد لحاظ شود تا Google Cloud Search اطلاعات مورد نیاز برای ارائه سطح صحیح دسترسی به مورد را داشته باشد.

Content Connector SDK مجموعه ای غنی از کلاس ها و روش های ACL را برای مدل سازی ACL های اکثر مخازن ارائه می دهد. شما باید ACL را برای هر مورد در مخزن خود تجزیه و تحلیل کنید و هنگامی که یک مورد را فهرست می کنید، ACL مربوطه را برای جستجوی ابری Google ایجاد کنید. اگر ACL مخزن شما از مفاهیمی مانند وراثت ACL استفاده می کند، مدل سازی آن ACL می تواند مشکل باشد. برای اطلاعات بیشتر در مورد Google Cloud Search ACL، به Google Cloud Search ACL مراجعه کنید.

توجه: Cloud Search Indexing API از ACL های تک دامنه پشتیبانی می کند. از ACL های متقابل دامنه پشتیبانی نمی کند. از کلاس Acl.Builder برای تنظیم دسترسی به هر آیتم با استفاده از یک ACL استفاده کنید. قطعه کد زیر، که از نمونه پیمایش کامل گرفته شده است، به همه کاربران یا "اصول" ( getCustomerPrincipal() ) اجازه می دهد تا "خوانندگان" همه موارد ( .setReaders() ) در هنگام انجام جستجو باشند.

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

شما باید ACL ها را درک کنید تا ACL ها را به درستی برای مخزن مدل سازی کنید. برای مثال، ممکن است فایل‌ها را در یک سیستم فایل فهرست‌بندی کنید که از نوعی مدل ارثی استفاده می‌کند که به موجب آن پوشه‌های فرزند مجوزها را از پوشه‌های والد به ارث می‌برند. مدل‌سازی وراثت ACL به اطلاعات بیشتری نیاز دارد که در ACLهای جستجوی ابری Google پوشش داده شده است

متادیتا را برای یک مورد تنظیم کنید

ابرداده در یک شیء 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 صف‌ها را حفظ می‌کند و محتویات صف را برای تعیین وضعیت مورد مقایسه می‌کند، مانند اینکه آیا یک مورد از مخزن حذف شده است یا خیر. برای اطلاعات بیشتر در مورد صف فهرست بندی جستجوی ابری، به صف فهرست بندی جستجوی ابری مراجعه کنید.

این بخش از اسناد به قطعات کد از مثال ListTraversalSample اشاره دارد.

نقطه ورودی کانکتور را پیاده سازی کنید

نقطه ورود به یک کانکتور روش main() است. وظیفه اصلی این متد ایجاد یک نمونه از کلاس Application و فراخوانی متد start() آن برای اجرای کانکتور است.

قبل از فراخوانی application.start() از کلاس IndexingApplication.Builder برای نمونه سازی الگوی ListingConnector استفاده کنید. ListingConnector یک شی Repository را می پذیرد که روش های آن را پیاده سازی می کنید. قطعه زیر نحوه نمونه سازی ListingConnector و Repository مرتبط با آن را نشان می دهد:

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

در پشت صحنه، SDK متد initConfig() را پس از فراخوانی متد main() کانکتور شما Application.build را فراخوانی می کند. متد initConfig() :

  1. متد Configuation.isInitialized() را فراخوانی می کند تا مطمئن شود که Configuration اولیه نشده است.
  2. یک شی Configuration با جفت های کلید-مقدار ارائه شده توسط Google راه اندازی می کند. هر جفت کلید-مقدار در یک شی ConfigValue در شی Configuration ذخیره می شود.

رابط Repository را پیاده سازی کنید

تنها هدف شی Repository انجام پیمایش و نمایه سازی آیتم های مخزن است. هنگام استفاده از یک الگو، فقط باید روش‌های خاصی را در رابط Repository لغو کنید تا یک رابط محتوا ایجاد کنید. روش هایی که نادیده می گیرید به الگو و استراتژی پیمایشی که استفاده می کنید بستگی دارد. برای ListingConnector ، روش‌های زیر را لغو کنید:

  • متد init() . برای انجام هرگونه راه اندازی و مقداردهی اولیه مخزن داده، روش init() را نادیده بگیرید.

  • متد getIds() . برای بازیابی شناسه ها و مقادیر هش برای همه رکوردهای موجود در مخزن، متد getIds() را لغو کنید.

  • متد getDoc() . برای افزودن موارد جدید، به روز رسانی، اصلاح یا حذف موارد از فهرست، متد getDoc() را لغو کنید.

  • (اختیاری) متد getChanges() . اگر مخزن شما از تشخیص تغییر پشتیبانی می کند، متد getChanges() را لغو کنید. این روش یک بار برای هر پیمایش افزایشی برنامه ریزی شده (همانطور که توسط پیکربندی شما تعریف شده است) فراخوانی می شود تا موارد اصلاح شده را بازیابی کرده و آنها را فهرست بندی کند.

  • (اختیاری) متد close() . اگر نیاز به پاکسازی مخزن دارید، متد close() لغو کنید. این روش یک بار در هنگام خاموش شدن کانکتور فراخوانی می شود.

هر یک از متدهای شی Repository نوعی از شیء ApiOperation را برمی گرداند. یک شیء ApiOperation عملی را به شکل یک یا شاید چند فراخوانی IndexingService.indexItem() انجام می دهد تا نمایه سازی واقعی مخزن شما را انجام دهد.

پارامترهای پیکربندی سفارشی را دریافت کنید

به عنوان بخشی از مدیریت پیکربندی کانکتور خود، باید هر پارامتر سفارشی را از شی Configuration دریافت کنید. این کار معمولاً در متد init() کلاس Repository انجام می شود.

کلاس Configuration چندین روش برای دریافت انواع داده های مختلف از یک پیکربندی دارد. هر متد یک شی ConfigValue را برمی گرداند. سپس از متد 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() را برای مدیریت هر آیتم در صف فهرست بندی جستجوی ابری نادیده بگیرید.

شناسه های مورد و مقادیر هش را فشار دهید

برای واکشی شناسه‌های آیتم و مقادیر هش محتوای مرتبط با آنها از مخزن، getIds() را لغو کنید. سپس جفت‌های ID و مقدار هش در درخواست عملیات فشار به صف فهرست‌سازی جستجوی ابری بسته‌بندی می‌شوند. شناسه های ریشه یا والد معمولاً ابتدا و سپس شناسه های فرزند تا زمانی که کل سلسله مراتب موارد پردازش شود، فشار داده می شود.

متد getIds() یک چک پوینت را می پذیرد که نشان دهنده آخرین موردی است که ایندکس می شود. در صورت قطع شدن فرآیند، می توان از نقطه بازرسی برای از سرگیری نمایه سازی در یک مورد خاص استفاده کرد. برای هر آیتم در مخزن خود، این مراحل را در متد getIds() انجام دهید:

  • شناسه هر مورد و مقدار هش مربوطه را از مخزن دریافت کنید.
  • هر جفت شناسه و مقدار هش را در یک PushItems بسته بندی کنید.
  • هر PushItems در یک تکرار کننده که توسط متد getIds() برگردانده شده است ترکیب کنید. توجه داشته باشید که getIds() در واقع یک CheckpointCloseableIterable را برمی گرداند که تکراری از اشیاء ApiOperation است، هر شی نشان دهنده یک درخواست API انجام شده در RepositoryDoc است، مانند فشار دادن آیتم ها به صف.

قطعه کد زیر نحوه دریافت شناسه و مقدار هش هر مورد و درج آنها را در PushItems نشان می دهد. PushItems یک درخواست ApiOperation برای فشار دادن یک آیتم به صف فهرست بندی جستجوی ابری است.

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;

موارد برای پردازش بیشتر به صف فهرست بندی جستجوی ابری منتقل می شوند.

هر مورد را بازیابی و مدیریت کنید

برای رسیدگی به هر آیتم در صف فهرست بندی جستجوی ابری، getDoc() لغو کنید. یک آیتم می تواند جدید، اصلاح شده، بدون تغییر باشد یا دیگر نمی تواند در مخزن منبع وجود داشته باشد. هر موردی را که جدید یا اصلاح شده است بازیابی و فهرست بندی کنید. مواردی را که دیگر در مخزن منبع وجود ندارند را از فهرست حذف کنید.

متد getDoc() یک آیتم را از صف فهرست بندی جستجوی ابری گوگل می پذیرد. برای هر آیتم در صف، این مراحل را در متد getDoc() انجام دهید:

  1. بررسی کنید که آیا شناسه مورد، در صف فهرست بندی جستجوی ابری، در مخزن وجود دارد یا خیر. اگر نه، مورد را از فهرست حذف کنید.

  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) را برگردانید تا مورد را از فهرست حذف کنید.

موارد بدون تغییر را مدیریت کنید

قطعه کد زیر نحوه نظرسنجی وضعیت مورد در صف فهرست بندی جستجوی ابری و مدیریت یک مورد بدون تغییر را نشان می دهد.

ListTraversalSample.java
String currentHash = this.calculateMetadataHash(documentId);
if (this.canSkipIndexing(item, currentHash)) {
  // Document neither modified nor deleted, ack the push
  log.info(() -> String.format("Document %s not modified", item.getName()));
  PushItem pushItem = new PushItem().setType("NOT_MODIFIED");
  return new PushItems.Builder().addPushItem(resourceName, pushItem).build();
}

برای تعیین اینکه آیا مورد اصلاح نشده است یا خیر، وضعیت مورد و همچنین سایر ابرداده هایی را که ممکن است نشان دهنده تغییر باشد بررسی کنید. در مثال، هش ابرداده برای تعیین اینکه آیا مورد تغییر کرده است یا خیر استفاده می شود.

ListTraversalSample.java
/**
 * Checks to see if an item is already up to date
 *
 * @param previousItem Polled item
 * @param currentHash  Metadata hash of the current github object
 * @return PushItem operation
 */
private boolean canSkipIndexing(Item previousItem, String currentHash) {
  if (previousItem.getStatus() == null || previousItem.getMetadata() == null) {
    return false;
  }
  String status = previousItem.getStatus().getCode();
  String previousHash = previousItem.getMetadata().getHash();
  return "ACCEPTED".equals(status)
      && previousHash != null
      && previousHash.equals(currentHash);
}

مجوزها را برای یک مورد تنظیم کنید

مخزن شما از یک لیست کنترل دسترسی (ACL) برای شناسایی کاربران یا گروه هایی که به یک آیتم دسترسی دارند استفاده می کند. ACL لیستی از شناسه ها برای گروه ها یا کاربرانی است که می توانند به آیتم دسترسی داشته باشند.

شما باید ACL مورد استفاده توسط مخزن خود را کپی کنید تا مطمئن شوید فقط آن دسته از کاربرانی که به یک مورد دسترسی دارند می توانند آن مورد را در یک نتیجه جستجو ببینند. ACL برای یک مورد باید هنگام نمایه سازی یک مورد لحاظ شود تا Google Cloud Search اطلاعات مورد نیاز برای ارائه سطح صحیح دسترسی به مورد را داشته باشد.

Content Connector SDK مجموعه ای غنی از کلاس ها و روش های ACL را برای مدل سازی ACL های اکثر مخازن ارائه می دهد. شما باید ACL را برای هر مورد در مخزن خود تجزیه و تحلیل کنید و هنگامی که یک مورد را فهرست می کنید، ACL مربوطه را برای جستجوی ابری Google ایجاد کنید. اگر ACL مخزن شما از مفاهیمی مانند وراثت ACL استفاده می کند، مدل سازی آن ACL می تواند مشکل باشد. برای اطلاعات بیشتر در مورد Google Cloud Search ACL، به Google Cloud Search ACL مراجعه کنید.

توجه: Cloud Search Indexing API از ACL های تک دامنه پشتیبانی می کند. از ACL های متقابل دامنه پشتیبانی نمی کند. از کلاس Acl.Builder برای تنظیم دسترسی به هر آیتم با استفاده از یک ACL استفاده کنید. قطعه کد زیر، که از نمونه پیمایش کامل گرفته شده است، به همه کاربران یا "اصول" ( getCustomerPrincipal() ) اجازه می دهد تا "خوانندگان" همه موارد ( .setReaders() ) در هنگام انجام جستجو باشند.

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

شما باید ACL ها را درک کنید تا ACL ها را به درستی برای مخزن مدل سازی کنید. برای مثال، ممکن است فایل‌ها را در یک سیستم فایل فهرست‌بندی کنید که از نوعی مدل ارثی استفاده می‌کند که به موجب آن پوشه‌های فرزند مجوزها را از پوشه‌های والد به ارث می‌برند. مدل‌سازی وراثت ACL به اطلاعات بیشتری نیاز دارد که در ACLهای جستجوی ابری Google پوشش داده شده است

متادیتا را برای یک مورد تنظیم کنید

ابرداده در یک شیء 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 است.

مراحل بعدی

در اینجا چند مرحله بعدی وجود دارد که ممکن است بردارید:

با استفاده از یک کلاس الگو، یک رابط پیمایش گراف ایجاد کنید

صف فهرست بندی Cloud Search برای نگهداری شناسه ها و مقادیر هش اختیاری برای هر مورد در مخزن استفاده می شود. یک رابط پیمایش گراف، شناسه‌های آیتم‌ها را به صف فهرست‌سازی Google Cloud Search منتقل می‌کند و آنها را یکی یکی برای نمایه‌سازی بازیابی می‌کند. Google Cloud Search صف‌ها را حفظ می‌کند و محتویات صف را برای تعیین وضعیت مورد مقایسه می‌کند، مانند اینکه آیا یک مورد از مخزن حذف شده است یا خیر. برای اطلاعات بیشتر در مورد صف نمایه سازی Cloud Search، به صف فهرست بندی جستجوی ابری Google مراجعه کنید.

در طول نمایه، محتوای آیتم از مخزن داده واکشی می‌شود و شناسه‌های آیتم‌های فرزند در صف قرار می‌گیرند. رابط به صورت بازگشتی شناسه‌های والدین و فرزندان را پردازش می‌کند تا زمانی که همه موارد رسیدگی شود.

این بخش از اسناد به قطعات کد از مثال GraphTraversalSample اشاره دارد.

نقطه ورودی کانکتور را پیاده سازی کنید

نقطه ورود به یک کانکتور روش main() است. وظیفه اصلی این متد ایجاد یک نمونه از کلاس Application و فراخوانی متد start() آن برای اجرای کانکتور است.

قبل از فراخوانی application.start() از کلاس IndexingApplication.Builder برای نمونه سازی الگوی ListingConnector استفاده کنید. ListingConnector یک شی Repository را می پذیرد که روش های آن را پیاده سازی می کنید.

قطعه زیر نحوه نمونه سازی ListingConnector و Repository مرتبط با آن را نشان می دهد:

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

در پشت صحنه، SDK متد initConfig() را پس از فراخوانی متد main() کانکتور شما Application.build را فراخوانی می کند. متد initConfig() :

  1. متد Configuation.isInitialized() را فراخوانی می کند تا مطمئن شود که Configuration اولیه نشده است.
  2. یک شی Configuration با جفت های کلید-مقدار ارائه شده توسط Google راه اندازی می کند. هر جفت کلید-مقدار در یک شی ConfigValue در شی Configuration ذخیره می شود.

رابط Repository را پیاده سازی کنید

تنها هدف شی Repository انجام پیمایش و نمایه سازی آیتم های مخزن است. هنگام استفاده از یک الگو، فقط باید روش‌های خاصی را در رابط Repository لغو کنید تا یک رابط محتوا ایجاد کنید. روش هایی که نادیده می گیرید به الگو و استراتژی پیمایشی که استفاده می کنید بستگی دارد. برای ListingConnector ، روش‌های زیر را لغو می‌کنید:

  • متد init() . برای انجام هرگونه راه اندازی و مقداردهی اولیه مخزن داده، روش init() را نادیده بگیرید.

  • متد getIds() . برای بازیابی شناسه ها و مقادیر هش برای همه رکوردهای موجود در مخزن، متد getIds() را لغو کنید.

  • متد getDoc() . برای افزودن موارد جدید، به روز رسانی، اصلاح یا حذف موارد از فهرست، متد getDoc() را لغو کنید.

  • (اختیاری) متد getChanges() . اگر مخزن شما از تشخیص تغییر پشتیبانی می کند، متد getChanges() را لغو کنید. این روش یک بار برای هر پیمایش افزایشی برنامه ریزی شده (همانطور که توسط پیکربندی شما تعریف شده است) فراخوانی می شود تا موارد اصلاح شده را بازیابی کرده و آنها را فهرست بندی کند.

  • (اختیاری) متد close() . اگر نیاز به پاکسازی مخزن دارید، متد close() لغو کنید. این روش یک بار در هنگام خاموش شدن کانکتور فراخوانی می شود.

هر یک از متدهای شی Repository نوعی از شیء ApiOperation را برمی گرداند. یک شیء ApiOperation عملی را به شکل یک یا شاید چند فراخوانی IndexingService.indexItem() انجام می دهد تا نمایه سازی واقعی مخزن شما را انجام دهد.

پارامترهای پیکربندی سفارشی را دریافت کنید

به عنوان بخشی از مدیریت پیکربندی کانکتور خود، باید هر پارامتر سفارشی را از شی Configuration دریافت کنید. این کار معمولاً در متد init() کلاس Repository انجام می شود.

کلاس Configuration چندین روش برای دریافت انواع داده های مختلف از یک پیکربندی دارد. هر متد یک شی ConfigValue را برمی گرداند. سپس از متد 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() را برای مدیریت هر آیتم در صف فهرست بندی جستجوی ابری نادیده بگیرید.

شناسه های مورد و مقادیر هش را فشار دهید

برای واکشی شناسه‌های آیتم و مقادیر هش محتوای مرتبط با آنها از مخزن، getIds() را لغو کنید. سپس جفت‌های ID و مقدار هش در درخواست عملیات فشار به صف فهرست‌سازی جستجوی ابری بسته‌بندی می‌شوند. شناسه های ریشه یا والد معمولاً ابتدا و سپس شناسه های فرزند تا زمانی که کل سلسله مراتب موارد پردازش شود، فشار داده می شود.

متد getIds() یک چک پوینت را می پذیرد که نشان دهنده آخرین موردی است که ایندکس می شود. در صورت قطع شدن فرآیند، می توان از نقطه بازرسی برای از سرگیری نمایه سازی در یک مورد خاص استفاده کرد. برای هر آیتم در مخزن خود، این مراحل را در متد getIds() انجام دهید:

  • شناسه هر مورد و مقدار هش مربوطه را از مخزن دریافت کنید.
  • Package each ID and hash value pair into a PushItems .
  • Combine each PushItems into an iterator returned by the getIds() method. Note that getIds() actually returns a CheckpointCloseableIterable which is an iteration of ApiOperation objects, each object representing an API request performed on a RepositoryDoc , such as push the items to the queue.

The following code snippet shows how to get each item ID and hash value and insert them into a PushItems . A PushItems is an ApiOperation request to push an item to the Cloud Search Indexing Queue.

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

The following code snippet shows how to use the PushItems.Builder class to package the IDs and hash values into a single push ApiOperation .

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

Items are pushed to the Cloud Search Indexing Queue for further processing.

Retrieve and handle each item

Override getDoc() to handle each item in the Cloud Search Indexing Queue. An item can be new, modified, unchanged, or can no longer exist in the source repository. Retrieve and index each item that is new or modified. Remove items from the index that no longer exist in the source repository.

The getDoc() method accepts an Item from the Cloud Search Indexing Queue. For each item in the queue, perform these steps in the getDoc() method:

  1. Check if the item's ID, within the Cloud Search Indexing Queue, exists in the repository. If not, delete the item from the index. If the item does exist, continue with the next step.

  2. Index changed or new items:

    1. Set the permissions.
    2. Set the metadata for the item that you are indexing.
    3. Combine the metadata and item into one indexable RepositoryDoc .
    4. Place the child IDs in the Cloud Search Indexing Queue for further processing.
    5. Return the RepositoryDoc .

Handle deleted items

The following code snippet shows how to determine if an item exists in the index and, it not, delete it.

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

Set the permissions for an item

Your repository uses an Access Control List (ACL) to identify the users or groups that have access to an item. An ACL is a list of IDs for groups or users who can access the item.

You must duplicate the ACL used by your repository to ensure only those users with access to an item can see that item within a search result. The ACL for an item must be included when indexing an item so that Google Cloud Search has the information it needs to provide the correct level of access to the item.

The Content Connector SDK provides a rich set of ACL classes and methods to model the ACLs of most repositories. You must analyze the ACL for each item in your repository and create a corresponding ACL for Google Cloud Search when you index an item. If your repository's ACL employs concepts such as ACL inheritance, modeling that ACL can be tricky. For further information on Google Cloud Search ACLs, refer to Google Cloud Search ACLs .

Note: The Cloud Search Indexing API supports single-domain ACLs. It does not support cross-domain ACLs. Use the Acl.Builder class to set access to each item using an ACL. The following code snippet, taken from the full traversal sample, allows all users or “principals” ( getCustomerPrincipal() ) to be “readers” of all items ( .setReaders() ) when performing a search.

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

You need to understand ACLs to properly model ACLs for the repository. For example, you might be indexing files within a file system that uses some sort of inheritance model whereby child folders inherit permissions from parent folders. Modeling ACL inheritance requires additional information covered in Google Cloud Search ACLs

Set the metadata for an item

Metadata is stored in an Item object. To create an Item , you need a minimum of a unique string ID, item type, ACL, URL, and version for the item. The following code snippet shows how to build an Item using the IndexingItemBuilder helper class.

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

Create the indexable item

Once you have set the metadata for the item, you can create the actual indexable item using the RepositoryDoc.Builder . The following example shows how to create a single indexable item.

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

A RepositoryDoc is a type of ApiOperation that performs the actual IndexingService.indexItem() request.

You can also use the setRequestMode() method of the RepositoryDoc.Builder class to identify the indexing request as ASYNCHRONOUS or SYNCHRONOUS :

ASYNCHRONOUS
Asynchronous mode results in longer indexing-to-serving latency and accommodates large throughput quota for indexing requests. Asynchronous mode is recommended for initial indexing (backfill) of the entire repository.
SYNCHRONOUS
Synchronous mode results in shorter indexing-to-serving latency and accommodates limited throughput quota. Synchronous mode is recommended for indexing of updates and changes to the repository. If unspecified, the request mode defaults to SYNCHRONOUS .

Place the child IDs in the Cloud Search Indexing Queue

The following code snippet shows how to include the child IDs, for the currently processing parent item, into the queue for processing. These IDs are processed after the parent item is indexed.

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

مراحل بعدی

Here are a few next steps you might take:

Create a content connector using the REST API

The following sections explain how to create a content connector using the REST API.

Determine your traversal strategy

The primary function of a content connector is to traverse a repository and index its data. You must implement a traversal strategy based on the size and layout of data in your repository. Following are three common traversal strategies:

Full traversal strategy

A full traversal strategy scans the entire repository and blindly indexes every item. This strategy is commonly used when you have a small repository and can afford the overhead of doing a full traversal every time you index.

This traversal strategy is suitable for small repositories with mostly static, non-hierarchical, data. You might also use this traversal strategy when change detection is difficult or not supported by the repository.

List traversal strategy

A list traversal strategy scans the entire repository, including all child nodes, determining the status of each item. Then, the connector takes a second pass and only indexes items that are new or have been updated since the last indexing. This strategy is commonly used to perform incremental updates to an existing index (instead of having to do a full traversal every time you update the index).

This traversal strategy is suitable when change detection is difficult or not supported by the repository, you have non-hierarchical data, and you are working with very large data sets.

پیمایش نمودار

A graph traversal strategy scans the entire parent node determining the status of each item. Then, the connector takes a second pass and only indexes items in the root node are new or have been updated since the last indexing. Finally, the connector passes any child IDs then indexes items in the child nodes that are new or have been updated. The connector continues recursively through all child nodes until all items have been addressed. Such traversal is typically used for hierarchical repositories where listing of all IDs isn't practical.

This strategy is suitable if you have hierarchical data that needs to be crawled, such as a series directories or web pages.

Implement your traversal strategy and index items

Every indexable element for Cloud Search is referred to as an item in the Cloud Search API. An item might be a file, folder, a line in a CSV file, or a database record.

Once your schema is registered, you can populate the index by:

  1. (optional) Using items.upload to upload files larger than 100KiB for indexing. For smaller files, embed the content as inlineContent using items.index .

  2. (optional) Using media.upload to upload media files for indexing.

  3. Using items.index to index the item. For example, if your schema uses the object definition in the movie schema , an indexing request for a single item would look like this:

    {
      "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. (Optional) Using items.get calls to verify an item has been indexed.

To perform a full traversal, you would periodically reindex the entire repository. To perform a list or graph traversal, you need to implement code to handle repository changes .

Handle repository changes

You can periodically gather and index each item from a repository to perform a full indexing. While effective at ensuring your index is up-to-date, a full indexing can be costly when dealing with larger or hierarchical repositories.

Instead of using index calls to index an entire repository every so often, you can also use the Google Cloud Indexing Queue as a mechanism for tracking changes and only indexing those items that have changed. You can use the items.push requests to push items into the queue for later polling and updating. For more information on the Google Cloud Indexing Queue, refer to Google Cloud Indexing Queue .

For further information on the Google Cloud Search API, refer to Cloud Search API .