অ্যাপসার্চ

AppSearch হল স্থানীয়ভাবে সঞ্চিত, স্ট্রাকচার্ড ডেটা পরিচালনা করার জন্য একটি উচ্চ-পারফরম্যান্স অন-ডিভাইস অনুসন্ধান সমাধান। এটিতে ডেটা ইন্ডেক্সিং এবং পূর্ণ-পাঠ্য অনুসন্ধান ব্যবহার করে ডেটা পুনরুদ্ধারের জন্য API রয়েছে। অ্যাপ্লিকেশনগুলি অ্যাপসার্চ ব্যবহার করে কাস্টম ইন-অ্যাপ অনুসন্ধান ক্ষমতাগুলি অফার করতে পারে, যা ব্যবহারকারীদের অফলাইনে থাকাকালীনও সামগ্রী অনুসন্ধান করতে দেয়৷

অ্যাপসার্চের মধ্যে সূচীকরণ এবং অনুসন্ধানের চিত্র তুলে ধরা হয়েছে

AppSearch নিম্নলিখিত বৈশিষ্ট্য প্রদান করে:

  • কম I/O ব্যবহার সহ একটি দ্রুত, মোবাইল-প্রথম স্টোরেজ বাস্তবায়ন
  • বৃহৎ ডেটা সেটের উপর অত্যন্ত দক্ষ সূচীকরণ এবং অনুসন্ধান
  • বহু-ভাষা সমর্থন, যেমন ইংরেজি এবং স্প্যানিশ
  • প্রাসঙ্গিকতা র‌্যাঙ্কিং এবং ব্যবহার স্কোরিং

কম I/O ব্যবহারের কারণে, AppSearch SQLite-এর তুলনায় বড় ডেটাসেটগুলিতে ইন্ডেক্সিং এবং অনুসন্ধানের জন্য কম লেটেন্সি অফার করে। AppSearch একক প্রশ্ন সমর্থন করে ক্রস-টাইপ কোয়েরি সহজ করে যেখানে SQLite একাধিক টেবিল থেকে ফলাফল একত্রিত করে।

অ্যাপসার্চের বৈশিষ্ট্যগুলি ব্যাখ্যা করতে, আসুন একটি মিউজিক অ্যাপ্লিকেশনের উদাহরণ নেওয়া যাক যা ব্যবহারকারীদের পছন্দের গানগুলি পরিচালনা করে এবং ব্যবহারকারীদের সহজেই সেগুলি অনুসন্ধান করতে দেয়৷ ব্যবহারকারীরা বিভিন্ন ভাষায় গানের শিরোনাম সহ বিশ্বজুড়ে সঙ্গীত উপভোগ করেন, যা অ্যাপসার্চ নেটিভভাবে সূচীকরণ এবং অনুসন্ধানের জন্য সমর্থন করে। ব্যবহারকারী যখন শিরোনাম বা শিল্পীর নাম দ্বারা একটি গানের জন্য অনুসন্ধান করে, অ্যাপ্লিকেশনটি সহজভাবে অ্যাপসার্চের কাছে অনুরোধটি দ্রুত এবং দক্ষতার সাথে মিলে যাওয়া গানগুলি পুনরুদ্ধার করে। অ্যাপ্লিকেশনটি ফলাফল প্রকাশ করে, এর ব্যবহারকারীদের দ্রুত তাদের প্রিয় গানগুলি বাজানো শুরু করতে দেয়।

সেটআপ

আপনার অ্যাপ্লিকেশনে AppSearch ব্যবহার করতে, আপনার অ্যাপ্লিকেশনের build.gradle ফাইলে নিম্নলিখিত নির্ভরতা যোগ করুন:

গ্রোভি

dependencies {
    def appsearch_version = "1.1.0-alpha05"

    implementation "androidx.appsearch:appsearch:$appsearch_version"
    // Use kapt instead of annotationProcessor if writing Kotlin classes
    annotationProcessor "androidx.appsearch:appsearch-compiler:$appsearch_version"

    implementation "androidx.appsearch:appsearch-local-storage:$appsearch_version"
    // PlatformStorage is compatible with Android 12+ devices, and offers additional features
    // to LocalStorage.
    implementation "androidx.appsearch:appsearch-platform-storage:$appsearch_version"
}

কোটলিন

dependencies {
    val appsearch_version = "1.1.0-alpha05"

    implementation("androidx.appsearch:appsearch:$appsearch_version")
    // Use annotationProcessor instead of kapt if writing Java classes
    kapt("androidx.appsearch:appsearch-compiler:$appsearch_version")

    implementation("androidx.appsearch:appsearch-local-storage:$appsearch_version")
    // PlatformStorage is compatible with Android 12+ devices, and offers additional features
    // to LocalStorage.
    implementation("androidx.appsearch:appsearch-platform-storage:$appsearch_version")
}

AppSearch ধারণা

নিম্নলিখিত চিত্রটি AppSearch ধারণা এবং তাদের মিথস্ক্রিয়াগুলিকে চিত্রিত করে৷

চিত্র একটি ক্লায়েন্ট অ্যাপ্লিকেশনের রূপরেখা এবং নিম্নলিখিতগুলির সাথে এর মিথস্ক্রিয়া AppSearch ধারণা: AppSearch ডাটাবেস, স্কিমা, স্কিমার প্রকার, নথি, অধিবেশন, এবং অনুসন্ধান. চিত্র 1. অ্যাপসার্চ ধারণার ডায়াগ্রাম: অ্যাপসার্চ ডাটাবেস, স্কিমা, স্কিমার ধরন, নথি, সেশন এবং অনুসন্ধান।

ডাটাবেস এবং সেশন

একটি AppSearch ডাটাবেস হল নথিগুলির একটি সংগ্রহ যা ডাটাবেস স্কিমার সাথে সামঞ্জস্যপূর্ণ। ক্লায়েন্ট অ্যাপ্লিকেশনগুলি তাদের অ্যাপ্লিকেশন প্রসঙ্গ এবং একটি ডাটাবেস নাম প্রদান করে একটি ডাটাবেস তৈরি করে। ডাটাবেস শুধুমাত্র তাদের তৈরি করা অ্যাপ্লিকেশন দ্বারা খোলা যেতে পারে। যখন একটি ডাটাবেস খোলা হয়, তখন ডাটাবেসের সাথে ইন্টারঅ্যাক্ট করার জন্য একটি সেশন ফিরে আসে। সেশন হল AppSearch API-কে কল করার এন্ট্রি পয়েন্ট এবং ক্লায়েন্ট অ্যাপ্লিকেশন দ্বারা এটি বন্ধ না হওয়া পর্যন্ত খোলা থাকে।

স্কিমা এবং স্কিমা প্রকার

একটি স্কিমা একটি AppSearch ডাটাবেসের মধ্যে ডেটার সাংগঠনিক কাঠামো উপস্থাপন করে।

স্কিমা স্কিমা প্রকারের সমন্বয়ে গঠিত যা অনন্য ধরণের ডেটা উপস্থাপন করে। স্কিমার প্রকারগুলি এমন বৈশিষ্ট্যগুলি নিয়ে গঠিত যাতে একটি নাম, ডেটা টাইপ এবং কার্ডিনালিটি থাকে। একবার ডাটাবেস স্কিমাতে একটি স্কিমা টাইপ যোগ করা হলে, সেই স্কিমা টাইপের ডকুমেন্ট তৈরি করা যায় এবং ডাটাবেসে যোগ করা যায়।

নথিপত্র

অ্যাপসার্চে, ডেটার একটি ইউনিট একটি নথি হিসাবে উপস্থাপন করা হয়। একটি AppSearch ডাটাবেসের প্রতিটি নথির নামস্থান এবং ID দ্বারা স্বতন্ত্রভাবে চিহ্নিত করা হয়। যখন শুধুমাত্র একটি উৎস যেমন ব্যবহারকারীর অ্যাকাউন্টের জন্য অনুসন্ধান করা প্রয়োজন তখন বিভিন্ন উৎস থেকে ডেটা আলাদা করতে নেমস্পেস ব্যবহার করা হয়।

নথিতে একটি তৈরির টাইমস্ট্যাম্প, একটি টাইম-টু-লাইভ (TTL) এবং একটি স্কোর রয়েছে যা পুনরুদ্ধারের সময় র‌্যাঙ্কিংয়ের জন্য ব্যবহার করা যেতে পারে। একটি নথিতে একটি স্কিমা প্রকারও বরাদ্দ করা হয় যা নথিতে থাকা আবশ্যক অতিরিক্ত ডেটা বৈশিষ্ট্যগুলি বর্ণনা করে।

একটি নথি শ্রেণী একটি নথির একটি বিমূর্ততা। এটিতে টীকাযুক্ত ক্ষেত্র রয়েছে যা একটি নথির বিষয়বস্তুকে প্রতিনিধিত্ব করে। ডিফল্টরূপে, ডকুমেন্ট ক্লাসের নাম স্কিমা টাইপের নাম সেট করে।

নথিগুলি সূচিত করা হয় এবং একটি প্রশ্ন প্রদান করে অনুসন্ধান করা যেতে পারে। একটি নথি মিলে যায় এবং অনুসন্ধানের ফলাফলে অন্তর্ভুক্ত করা হয় যদি এতে ক্যোয়ারীতে থাকা শর্তাবলী থাকে বা অন্য অনুসন্ধানের স্পেসিফিকেশনের সাথে মেলে। ফলাফল তাদের স্কোর এবং র্যাঙ্কিং কৌশল উপর ভিত্তি করে আদেশ করা হয়. অনুসন্ধান ফলাফলগুলি এমন পৃষ্ঠাগুলির দ্বারা প্রতিনিধিত্ব করা হয় যা আপনি ক্রমানুসারে পুনরুদ্ধার করতে পারেন৷

AppSearch অনুসন্ধানের জন্য কাস্টমাইজেশন অফার করে, যেমন ফিল্টার, পৃষ্ঠার আকার কনফিগারেশন এবং স্নিপেটিং।

প্ল্যাটফর্ম স্টোরেজ, লোকাল স্টোরেজ বা প্লে সার্ভিস স্টোরেজ

AppSearch তিনটি স্টোরেজ সমাধান অফার করে: LocalStorage , PlatformStorage এবং PlayServicesStorageLocalStorage এর সাথে, আপনার অ্যাপ্লিকেশন একটি অ্যাপ-নির্দিষ্ট সূচক পরিচালনা করে যা আপনার অ্যাপ্লিকেশন ডেটা ডিরেক্টরিতে থাকে। PlatformStorage এবং PlayServicesStorage উভয়ের সাথে, আপনার অ্যাপ্লিকেশন একটি সিস্টেম-ব্যাপী কেন্দ্রীয় সূচকে অবদান রাখে। PlatformStorage সূচী সিস্টেম সার্ভারে হোস্ট করা হয় এবং PlayServicesStorage এর সূচী Google Play পরিষেবার স্টোরেজে হোস্ট করা হয়। এই কেন্দ্রীয় সূচীগুলির মধ্যে ডেটা অ্যাক্সেস আপনার অ্যাপ্লিকেশনে অবদান রাখা ডেটা এবং অন্য অ্যাপ্লিকেশন দ্বারা স্পষ্টভাবে আপনার সাথে ভাগ করা ডেটাতে সীমাবদ্ধ। এই সমস্ত স্টোরেজ বিকল্প একই API ভাগ করে এবং একটি ডিভাইসের সংস্করণের উপর ভিত্তি করে বিনিময় করা যেতে পারে:

কোটলিন

if (BuildCompat.isAtLeastS()) {
    appSearchSessionFuture.setFuture(
        PlatformStorage.createSearchSession(
            PlatformStorage.SearchContext.Builder(mContext, DATABASE_NAME)
               .build()
        )
    )
} else {
    if (usePlayServicesStorageBelowS) {
        appSearchSessionFuture.setFuture(
            PlayServicesStorage.createSearchSession(
                PlayServicesStorage.SearchContext.Builder(mContext, DATABASE_NAME)
                    .build()
            )
        )
    } else {
        appSearchSessionFuture.setFuture(
            LocalStorage.createSearchSession(
                LocalStorage.SearchContext.Builder(mContext, DATABASE_NAME)
                    .build()
            )
        )
    }
}

জাভা

if (BuildCompat.isAtLeastS()) {
    mAppSearchSessionFuture.setFuture(PlatformStorage.createSearchSession(
            new PlatformStorage.SearchContext.Builder(mContext, DATABASE_NAME)
                    .build()));
} else {
    if (usePlayServicesStorageBelowS) {
        mAppSearchSessionFuture.setFuture(PlayServicesStorage.createSearchSession(
                new PlayServicesStorage.SearchContext.Builder(mContext, DATABASE_NAME)
                        .build()));
    } else {
        mAppSearchSessionFuture.setFuture(LocalStorage.createSearchSession(
                new LocalStorage.SearchContext.Builder(mContext, DATABASE_NAME)
                        .build()));
    }
}

PlatformStorage এবং PlayServicesStorage ব্যবহার করে, আপনার অ্যাপ্লিকেশন নিরাপদে অন্যান্য অ্যাপ্লিকেশনের সাথে ডেটা ভাগ করে নিতে পারে যাতে তারা আপনার অ্যাপের ডেটা অনুসন্ধান করতে পারে৷ অন্য অ্যাপ্লিকেশনের ডেটা পড়ার অনুমতি আছে কিনা তা নিশ্চিত করতে একটি শংসাপত্র হ্যান্ডশেক ব্যবহার করে শুধুমাত্র-পঠন অ্যাপ্লিকেশন ডেটা শেয়ারিং মঞ্জুর করা হয়। setSchemaTypeVisibilityForPackage() এর জন্য ডকুমেন্টেশনে এই API সম্পর্কে আরও পড়ুন।

উপরন্তু PlatformStorage সাথে, সূচীকৃত ডেটা সিস্টেম UI পৃষ্ঠগুলিতে প্রদর্শিত হতে পারে। অ্যাপ্লিকেশনগুলি তাদের কিছু বা সমস্ত ডেটা সিস্টেম UI পৃষ্ঠগুলিতে প্রদর্শিত হওয়া থেকে অপ্ট আউট করতে পারে৷ setSchemaTypeDisplayedBySystem() এর জন্য ডকুমেন্টেশনে এই API সম্পর্কে আরও পড়ুন।

বৈশিষ্ট্য LocalStorage (Android 5.0+ এর সাথে সামঞ্জস্যপূর্ণ) PlatformStorage (Android 12+ এর সাথে সামঞ্জস্যপূর্ণ) PlayServicesStorage (Android 5.0+ এর সাথে সামঞ্জস্যপূর্ণ)
দক্ষ পূর্ণ-পাঠ্য অনুসন্ধান
বহু-ভাষা সমর্থন
বাইনারি আকার হ্রাস
অ্যাপ্লিকেশন-টু-অ্যাপ্লিকেশন ডেটা ভাগ করে নেওয়া
সিস্টেম UI পৃষ্ঠতলের ডেটা প্রদর্শন করার ক্ষমতা
সীমাহীন নথির আকার এবং গণনা সূচিত করা যেতে পারে
অতিরিক্ত বাইন্ডার লেটেন্সি ছাড়াই দ্রুত অপারেশন

LocalStorage এবং PlatformStorage মধ্যে নির্বাচন করার সময় বিবেচনা করার জন্য অতিরিক্ত ট্রেড-অফ রয়েছে৷ যেহেতু PlatformStorage অ্যাপসার্চ সিস্টেম পরিষেবার উপর জেটপ্যাক এপিআইগুলিকে আবৃত করে, স্থানীয় স্টোরেজ ব্যবহারের তুলনায় APK আকারের প্রভাব ন্যূনতম। যাইহোক, এর মানে হল AppSearch সিস্টেম পরিষেবাতে কল করার সময় AppSearch অপারেশনগুলি অতিরিক্ত বাইন্ডার লেটেন্সি বহন করে। PlatformStorage সাথে, অ্যাপসার্চ একটি দক্ষ কেন্দ্রীয় সূচক নিশ্চিত করতে একটি অ্যাপ্লিকেশন সূচক করতে পারে এমন নথির সংখ্যা এবং নথির আকার সীমিত করে। PlayServicesStorage এও PlatformStorage মতো একই সীমাবদ্ধতা রয়েছে এবং এটি শুধুমাত্র Google Play পরিষেবার ডিভাইসে সমর্থিত।

অ্যাপসার্চ দিয়ে শুরু করুন

একটি অনুমানমূলক নোট-কিপিং অ্যাপ্লিকেশানের সাথে একীভূত করতে কীভাবে অ্যাপসার্চ এপিআই ব্যবহার করতে হয় তা এই বিভাগের উদাহরণটি দেখায়।

একটি নথি ক্লাস লিখুন

অ্যাপসার্চের সাথে সংহত করার প্রথম ধাপ হল ডাটাবেসে সন্নিবেশ করার জন্য ডেটা বর্ণনা করার জন্য একটি নথির শ্রেণী লেখা। @Document টীকা ব্যবহার করে একটি শ্রেণীকে নথির শ্রেণী হিসেবে চিহ্নিত করুন। আপনি ডকুমেন্ট ক্লাসের ইনস্ট্যান্স ব্যবহার করে ডকুমেন্ট রাখতে এবং ডাটাবেস থেকে নথি পুনরুদ্ধার করতে পারেন।

নিচের কোডটি একটি নোট অবজেক্টের টেক্সট ইন্ডেক্স করার জন্য @Document.StringProperty টীকাযুক্ত ক্ষেত্র সহ একটি নোট নথি ক্লাস সংজ্ঞায়িত করে।

কোটলিন

@Document
public data class Note(

    // Required field for a document class. All documents MUST have a namespace.
    @Document.Namespace
    val namespace: String,

    // Required field for a document class. All documents MUST have an Id.
    @Document.Id
    val id: String,

    // Optional field for a document class, used to set the score of the
    // document. If this is not included in a document class, the score is set
    // to a default of 0.
    @Document.Score
    val score: Int,

    // Optional field for a document class, used to index a note's text for this
    // document class.
    @Document.StringProperty(indexingType = AppSearchSchema.StringPropertyConfig.INDEXING_TYPE_PREFIXES)
    val text: String
)

জাভা

@Document
public class Note {

  // Required field for a document class. All documents MUST have a namespace.
  @Document.Namespace
  private final String namespace;

  // Required field for a document class. All documents MUST have an Id.
  @Document.Id
  private final String id;

  // Optional field for a document class, used to set the score of the
  // document. If this is not included in a document class, the score is set
  // to a default of 0.
  @Document.Score
  private final int score;

  // Optional field for a document class, used to index a note's text for this
  // document class.
  @Document.StringProperty(indexingType = StringPropertyConfig.INDEXING_TYPE_PREFIXES)
  private final String text;

  Note(@NonNull String id, @NonNull String namespace, int score, @NonNull String text) {
    this.id = Objects.requireNonNull(id);
    this.namespace = Objects.requireNonNull(namespace);
    this.score = score;
    this.text = Objects.requireNonNull(text);
  }

  @NonNull
  public String getNamespace() {
    return namespace;
  }

  @NonNull
  public String getId() {
    return id;
  }

  public int getScore() {
    return score;
  }

  @NonNull
  public String getText() {
     return text;
  }
}

একটি ডাটাবেস খুলুন

ডকুমেন্ট নিয়ে কাজ করার আগে আপনাকে অবশ্যই একটি ডাটাবেস তৈরি করতে হবে। নিম্নলিখিত কোডটি notes_app নামের একটি নতুন ডাটাবেস তৈরি করে এবং একটি AppSearchSession জন্য একটি ListenableFuture পায়, যা ডাটাবেসের সাথে সংযোগের প্রতিনিধিত্ব করে এবং ডাটাবেস অপারেশনের জন্য API প্রদান করে।

কোটলিন

val context: Context = getApplicationContext()
val sessionFuture = LocalStorage.createSearchSession(
    LocalStorage.SearchContext.Builder(context, /*databaseName=*/"notes_app")
    .build()
)

জাভা

Context context = getApplicationContext();
ListenableFuture<AppSearchSession> sessionFuture = LocalStorage.createSearchSession(
       new LocalStorage.SearchContext.Builder(context, /*databaseName=*/ "notes_app")
               .build()
);

একটি স্কিমা সেট করুন

ডাটাবেস থেকে দস্তাবেজগুলি পুনরুদ্ধার করার আগে আপনাকে অবশ্যই একটি স্কিমা সেট করতে হবে। ডাটাবেস স্কিমা বিভিন্ন ধরনের স্ট্রাকচার্ড ডেটা নিয়ে গঠিত, যাকে "স্কিমা প্রকার" বলা হয়। নিম্নলিখিত কোড একটি স্কিমা টাইপ হিসাবে ডকুমেন্ট ক্লাস প্রদান করে স্কিমা সেট করে।

কোটলিন

val setSchemaRequest = SetSchemaRequest.Builder().addDocumentClasses(Note::class.java)
    .build()
val setSchemaFuture = Futures.transformAsync(
    sessionFuture,
    { session ->
        session?.setSchema(setSchemaRequest)
    }, mExecutor
)

জাভা

SetSchemaRequest setSchemaRequest = new SetSchemaRequest.Builder().addDocumentClasses(Note.class)
       .build();
ListenableFuture<SetSchemaResponse> setSchemaFuture =
       Futures.transformAsync(sessionFuture, session -> session.setSchema(setSchemaRequest), mExecutor);

ডাটাবেসে একটি নথি রাখুন

একবার একটি স্কিমা টাইপ যোগ করা হলে, আপনি ডাটাবেসে সেই ধরনের নথি যোগ করতে পারেন। নিচের কোডটি Note ডকুমেন্ট ক্লাস বিল্ডার ব্যবহার করে স্কিমা ধরনের Note একটি নথি তৈরি করে। এটি এই নমুনার একটি নির্বিচারে ব্যবহারকারীর প্রতিনিধিত্ব করতে নথির নামস্থান user1 সেট করে। ডকুমেন্টটি তারপর ডাটাবেসে ঢোকানো হয় এবং পুট অপারেশনের ফলাফল প্রক্রিয়া করার জন্য একজন শ্রোতা সংযুক্ত করা হয়।

কোটলিন

val note = Note(
    namespace="user1",
    id="noteId",
    score=10,
    text="Buy fresh fruit"
)

val putRequest = PutDocumentsRequest.Builder().addDocuments(note).build()
val putFuture = Futures.transformAsync(
    sessionFuture,
    { session ->
        session?.put(putRequest)
    }, mExecutor
)

Futures.addCallback(
    putFuture,
    object : FutureCallback<AppSearchBatchResult<String, Void>?> {
        override fun onSuccess(result: AppSearchBatchResult<String, Void>?) {

            // Gets map of successful results from Id to Void
            val successfulResults = result?.successes

            // Gets map of failed results from Id to AppSearchResult
            val failedResults = result?.failures
        }

        override fun onFailure(t: Throwable) {
            Log.e(TAG, "Failed to put documents.", t)
        }
    },
    mExecutor
)

জাভা

Note note = new Note(/*namespace=*/"user1", /*id=*/
                "noteId", /*score=*/ 10, /*text=*/ "Buy fresh fruit!");

PutDocumentsRequest putRequest = new PutDocumentsRequest.Builder().addDocuments(note)
       .build();
ListenableFuture<AppSearchBatchResult<String, Void>> putFuture =
       Futures.transformAsync(sessionFuture, session -> session.put(putRequest), mExecutor);

Futures.addCallback(putFuture, new FutureCallback<AppSearchBatchResult<String, Void>>() {
   @Override
   public void onSuccess(@Nullable AppSearchBatchResult<String, Void> result) {

     // Gets map of successful results from Id to Void
     Map<String, Void> successfulResults = result.getSuccesses();

     // Gets map of failed results from Id to AppSearchResult
     Map<String, AppSearchResult<Void>> failedResults = result.getFailures();
   }

   @Override
   public void onFailure(@NonNull Throwable t) {
      Log.e(TAG, "Failed to put documents.", t);
   }
}, mExecutor);

আপনি এই বিভাগে আচ্ছাদিত অনুসন্ধান অপারেশন ব্যবহার করে সূচীকৃত নথিগুলি অনুসন্ধান করতে পারেন। নিম্নলিখিত কোড user1 নামস্থানের অন্তর্গত নথিগুলির জন্য ডাটাবেসের উপর "ফল" শব্দটির জন্য প্রশ্নগুলি সম্পাদন করে৷

কোটলিন

val searchSpec = SearchSpec.Builder()
    .addFilterNamespaces("user1")
    .build();

val searchFuture = Futures.transform(
    sessionFuture,
    { session ->
        session?.search("fruit", searchSpec)
    },
    mExecutor
)
Futures.addCallback(
    searchFuture,
    object : FutureCallback<SearchResults> {
        override fun onSuccess(searchResults: SearchResults?) {
            iterateSearchResults(searchResults)
        }

        override fun onFailure(t: Throwable?) {
            Log.e("TAG", "Failed to search notes in AppSearch.", t)
        }
    },
    mExecutor
)

জাভা

SearchSpec searchSpec = new SearchSpec.Builder()
       .addFilterNamespaces("user1")
       .build();

ListenableFuture<SearchResults> searchFuture =
       Futures.transform(sessionFuture, session -> session.search("fruit", searchSpec),
       mExecutor);

Futures.addCallback(searchFuture,
       new FutureCallback<SearchResults>() {
           @Override
           public void onSuccess(@Nullable SearchResults searchResults) {
               iterateSearchResults(searchResults);
           }

           @Override
           public void onFailure(@NonNull Throwable t) {
               Log.e(TAG, "Failed to search notes in AppSearch.", t);
           }
       }, mExecutor);

অনুসন্ধান ফলাফলের মাধ্যমে পুনরাবৃত্তি করুন

অনুসন্ধানগুলি একটি SearchResults উদাহরণ প্রদান করে, যা SearchResult অবজেক্টের পৃষ্ঠাগুলিতে অ্যাক্সেস দেয়। প্রতিটি SearchResult এর মিলিত GenericDocument ধারণ করে, একটি নথির সাধারণ রূপ যা সমস্ত নথিতে রূপান্তরিত হয়। নিম্নলিখিত কোডটি অনুসন্ধান ফলাফলের প্রথম পৃষ্ঠা পায় এবং ফলাফলটিকে একটি Note নথিতে রূপান্তরিত করে।

কোটলিন

Futures.transform(
    searchResults?.nextPage,
    { page: List<SearchResult>? ->
        // Gets GenericDocument from SearchResult.
        val genericDocument: GenericDocument = page!![0].genericDocument
        val schemaType = genericDocument.schemaType
        val note: Note? = try {
            if (schemaType == "Note") {
                // Converts GenericDocument object to Note object.
                genericDocument.toDocumentClass(Note::class.java)
            } else null
        } catch (e: AppSearchException) {
            Log.e(
                TAG,
                "Failed to convert GenericDocument to Note",
                e
            )
            null
        }
        note
    },
    mExecutor
)

জাভা

Futures.transform(searchResults.getNextPage(), page -> {
  // Gets GenericDocument from SearchResult.
  GenericDocument genericDocument = page.get(0).getGenericDocument();
  String schemaType = genericDocument.getSchemaType();

  Note note = null;

  if (schemaType.equals("Note")) {
    try {
      // Converts GenericDocument object to Note object.
      note = genericDocument.toDocumentClass(Note.class);
    } catch (AppSearchException e) {
      Log.e(TAG, "Failed to convert GenericDocument to Note", e);
    }
  }

  return note;
}, mExecutor);

একটি নথি সরান

যখন ব্যবহারকারী একটি নোট মুছে ফেলে, অ্যাপ্লিকেশনটি ডেটাবেস থেকে সংশ্লিষ্ট Note নথিটি মুছে ফেলে। এটি নিশ্চিত করে যে নোটটি আর প্রশ্নের মধ্যে প্রদর্শিত হবে না। নিম্নলিখিত কোডটি আইডি দ্বারা ডাটাবেস থেকে Note নথিটি সরানোর জন্য একটি সুস্পষ্ট অনুরোধ করে।

কোটলিন

val removeRequest = RemoveByDocumentIdRequest.Builder("user1")
    .addIds("noteId")
    .build()

val removeFuture = Futures.transformAsync(
    sessionFuture, { session ->
        session?.remove(removeRequest)
    },
    mExecutor
)

জাভা

RemoveByDocumentIdRequest removeRequest = new RemoveByDocumentIdRequest.Builder("user1")
       .addIds("noteId")
       .build();

ListenableFuture<AppSearchBatchResult<String, Void>> removeFuture =
       Futures.transformAsync(sessionFuture, session -> session.remove(removeRequest), mExecutor);

ডিস্কে স্থির থাকুন

requestFlush() কল করে একটি ডাটাবেসের আপডেটগুলিকে পর্যায়ক্রমে ডিস্কে অব্যাহত রাখতে হবে। কলটি সফল হয়েছে কিনা তা নির্ধারণ করতে নিম্নলিখিত কোডটি একজন শ্রোতার সাথে requestFlush() কল করে।

কোটলিন

val requestFlushFuture = Futures.transformAsync(
    sessionFuture,
    { session -> session?.requestFlush() }, mExecutor
)

Futures.addCallback(requestFlushFuture, object : FutureCallback<Void?> {
    override fun onSuccess(result: Void?) {
        // Success! Database updates have been persisted to disk.
    }

    override fun onFailure(t: Throwable) {
        Log.e(TAG, "Failed to flush database updates.", t)
    }
}, mExecutor)

জাভা

ListenableFuture<Void> requestFlushFuture = Futures.transformAsync(sessionFuture,
        session -> session.requestFlush(), mExecutor);

Futures.addCallback(requestFlushFuture, new FutureCallback<Void>() {
    @Override
    public void onSuccess(@Nullable Void result) {
        // Success! Database updates have been persisted to disk.
    }

    @Override
    public void onFailure(@NonNull Throwable t) {
        Log.e(TAG, "Failed to flush database updates.", t);
    }
}, mExecutor);

একটি অধিবেশন বন্ধ করুন

একটি AppSearchSession বন্ধ করা উচিত যখন একটি অ্যাপ্লিকেশন আর কোনো ডাটাবেস অপারেশন কল করা হবে না। নিম্নলিখিত কোডটি অ্যাপসার্চ সেশন বন্ধ করে যা পূর্বে খোলা হয়েছিল এবং ডিস্কে সমস্ত আপডেট বজায় রাখে।

কোটলিন

val closeFuture = Futures.transform<AppSearchSession, Unit>(sessionFuture,
    { session ->
        session?.close()
        Unit
    }, mExecutor
)

জাভা

ListenableFuture<Void> closeFuture = Futures.transform(sessionFuture, session -> {
   session.close();
   return null;
}, mExecutor);

অতিরিক্ত সম্পদ

AppSearch সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত সংস্থানগুলি দেখুন:

নমুনা

মতামত প্রদান

এই সম্পদগুলির মাধ্যমে আমাদের সাথে আপনার প্রতিক্রিয়া এবং ধারণা শেয়ার করুন:

ইস্যু ট্র্যাকার

বাগ রিপোর্ট করুন যাতে আমরা সেগুলি ঠিক করতে পারি৷