AppSearch

AppSearch เป็นโซลูชันการค้นหาในอุปกรณ์ที่มีประสิทธิภาพสูงสำหรับจัดการ Structured Data ที่เก็บไว้ในเครื่อง ซึ่งประกอบด้วย API สําหรับการจัดทําดัชนีและการดึงข้อมูลโดยใช้การค้นหาข้อความแบบเต็ม แอปพลิเคชันสามารถใช้ AppSearch เพื่อมอบความสามารถในการค้นหาในแอปที่กําหนดเอง ซึ่งช่วยให้ผู้ใช้ค้นหาเนื้อหาได้แม้จะออฟไลน์อยู่

แผนภาพแสดงการจัดทําดัชนีและการค้นหาภายใน AppSearch

AppSearch มีฟีเจอร์ต่อไปนี้

  • การติดตั้งใช้งานพื้นที่เก็บข้อมูลที่รวดเร็วและเน้นอุปกรณ์เคลื่อนที่เป็นหลักโดยใช้ I/O ต่ำ
  • การจัดทำดัชนีและการค้นหาชุดข้อมูลขนาดใหญ่ที่มีประสิทธิภาพสูง
  • รองรับหลายภาษา เช่น อังกฤษและสเปน
  • การจัดอันดับความเกี่ยวข้องและการให้คะแนนการใช้งาน

AppSearch ใช้เวลาในการตอบสนองในการจัดทำดัชนีและการค้นหาชุดข้อมูลขนาดใหญ่ต่ำกว่า SQLite เนื่องจากมีการใช้ I/O น้อยกว่า AppSearch ลดความซับซ้อนในการค้นหาข้ามประเภทด้วยการรองรับการค้นหารายการเดียว ขณะที่ SQLite จะผสานผลการค้นหาจากหลายตาราง

มาดูตัวอย่างฟีเจอร์ของ AppSearch กันด้วยแอปพลิเคชันเพลงที่จัดการเพลงโปรดของผู้ใช้และช่วยให้ผู้ใช้ค้นหาเพลงเหล่านั้นได้อย่างง่ายดาย ผู้ใช้สามารถฟังเพลงจากทั่วโลกที่มีชื่อเพลงเป็นภาษาต่างๆ ซึ่ง AppSearch รองรับการจัดทำดัชนีและการค้นหาโดยกำเนิด เมื่อผู้ใช้ค้นหาเพลงตามชื่อหรือชื่อศิลปิน แอปพลิเคชันจะส่งคำขอไปยัง AppSearch เพื่อดึงข้อมูลเพลงที่ตรงกันอย่างรวดเร็วและมีประสิทธิภาพ แอปพลิเคชันจะแสดงผลลัพธ์ ซึ่งช่วยให้ผู้ใช้เริ่มเล่นเพลงโปรดได้อย่างรวดเร็ว

ตั้งค่า

หากต้องการใช้ AppSearch ในแอปพลิเคชัน ให้เพิ่มทรัพยากร Dependency ต่อไปนี้ลงในไฟล์ 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"
}

Kotlin

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, สคีมา, ประเภทสคีมา, เอกสาร, เซสชัน และการค้นหา

ฐานข้อมูลและเซสชัน

ฐานข้อมูล AppSearch คือคอลเล็กชันเอกสารที่เป็นไปตามสคีมาฐานข้อมูล แอปพลิเคชันไคลเอ็นต์สร้างฐานข้อมูลโดยระบุบริบทของแอปพลิเคชันและชื่อฐานข้อมูล มีเพียงแอปพลิเคชันที่สร้างขึ้นเท่านั้นที่เปิดฐานข้อมูลได้ เมื่อเปิดฐานข้อมูล ระบบจะแสดงเซสชันเพื่อโต้ตอบกับฐานข้อมูล เซสชันคือจุดแรกเข้าสำหรับการเรียกใช้ AppSearch API และจะยังคงเปิดอยู่จนกว่าแอปพลิเคชันไคลเอ็นต์จะปิด

สคีมาและประเภทสคีมา

สคีมาแสดงโครงสร้างองค์กรของข้อมูลภายในฐานข้อมูล AppSearch

สคีมาประกอบด้วยประเภทสคีมาที่แสดงถึงประเภทข้อมูลที่ไม่ซ้ำกัน ประเภทสคีมาประกอบด้วยพร็อพเพอร์ตี้ที่มีชื่อ ประเภทข้อมูล และ Cardinality เมื่อเพิ่มสคีมาประเภทหนึ่งลงในสคีมาฐานข้อมูลแล้ว คุณสามารถสร้างและเพิ่มเอกสารประเภทสคีมานั้นลงในฐานข้อมูลได้

เอกสาร

ใน AppSearch หน่วยข้อมูลจะแสดงเป็นเอกสาร เอกสารแต่ละรายการในฐานข้อมูล AppSearch จะระบุด้วยเนมสเปซและรหัสที่ไม่ซ้ำกัน เนมสเปซใช้เพื่อแยกข้อมูลจากแหล่งที่มาต่างๆ เมื่อต้องการค้นหาแหล่งที่มาเพียงแหล่งเดียว เช่น บัญชีผู้ใช้

เอกสารมีการประทับเวลาสร้าง, Time to Live (TTL) และคะแนนที่ใช้ในการจัดอันดับระหว่างการเรียกข้อมูล นอกจากนี้ ระบบจะกำหนดประเภทสคีมาให้กับเอกสาร ซึ่งอธิบายพร็อพเพอร์ตี้ข้อมูลเพิ่มเติมที่เอกสารต้องมี

คลาสเอกสารเป็นการแยกแยะเอกสาร ซึ่งมีช่องที่มีคำอธิบายประกอบซึ่งแสดงถึงเนื้อหาของเอกสาร โดยค่าเริ่มต้น ชื่อของคลาสเอกสารจะเป็นชื่อของประเภทสคีมา

ระบบจะจัดทําดัชนีเอกสารและค้นหาได้โดยระบุข้อความค้นหา ระบบจะจับคู่และรวมเอกสารไว้ในผลการค้นหาหากเอกสารมีคำในคำค้นหาหรือตรงกับข้อกำหนดการค้นหาอื่น ผลการค้นหาจะเรียงลําดับตามคะแนนและกลยุทธ์การจัดอันดับ ผลการค้นหาจะแสดงเป็นหน้าเว็บที่คุณเรียกดูได้ทีละหน้า

AppSearch มีการปรับแต่งการค้นหา เช่น ตัวกรอง การกำหนดค่าขนาดหน้าเว็บ และการตัดข้อมูล

พื้นที่เก็บข้อมูลแพลตฟอร์ม พื้นที่เก็บข้อมูลในเครื่อง หรือพื้นที่เก็บข้อมูลบริการ Play

AppSearch มีโซลูชันพื้นที่เก็บข้อมูล 3 รายการ ได้แก่ LocalStorage, PlatformStorage และ PlayServicesStorage เมื่อใช้ LocalStorage แอปพลิเคชันจะจัดการดัชนีเฉพาะแอปที่อยู่ในไดเรกทอรีข้อมูลแอปพลิเคชัน เมื่อใช้ทั้ง PlatformStorage และ PlayServicesStorage แอปพลิเคชันของคุณจะมีส่วนร่วมในดัชนีกลางทั่วทั้งระบบ ดัชนีของ PlatformStorage โฮสต์อยู่ในเซิร์ฟเวอร์ของระบบ และดัชนีของ PlayServicesStorage โฮสต์อยู่ในพื้นที่เก็บข้อมูลของบริการ Google Play การเข้าถึงข้อมูลภายในดัชนีกลางเหล่านี้จํากัดไว้เฉพาะข้อมูลที่แอปพลิเคชันของคุณให้ไว้และข้อมูลที่แอปพลิเคชันอื่นแชร์กับคุณอย่างชัดเจน ตัวเลือกพื้นที่เก็บข้อมูลทั้งหมดเหล่านี้ใช้ API เดียวกันและสามารถใช้แทนกันได้โดยขึ้นอยู่กับเวอร์ชันของอุปกรณ์

Kotlin

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

Java

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 แอปพลิเคชันของคุณจะสามารถแชร์ข้อมูลกับแอปพลิเคชันอื่นๆ อย่างปลอดภัยเพื่อให้แอปพลิเคชันเหล่านั้นค้นหาข้อมูลของแอปคุณได้ด้วย การแชร์ข้อมูลแอปพลิเคชันแบบอ่านอย่างเดียวจะได้รับการอนุญาตโดยใช้การจับมือด้วยใบรับรองเพื่อให้มั่นใจว่าแอปพลิเคชันอื่นมีสิทธิ์อ่านข้อมูล อ่านข้อมูลเพิ่มเติมเกี่ยวกับ API นี้ในเอกสารประกอบสำหรับ setSchemaTypeVisibilityForPackage()

นอกจากนี้ PlatformStorage ยังช่วยให้ข้อมูลที่จัดทำดัชนีแสดงในแพลตฟอร์ม UI ของระบบได้ แอปพลิเคชันสามารถเลือกไม่ใช้การแสดงข้อมูลบางส่วนหรือทั้งหมดบนแพลตฟอร์ม UI ของระบบ อ่านข้อมูลเพิ่มเติมเกี่ยวกับ API นี้ในเอกสารประกอบของ setSchemaTypeDisplayedBySystem()

ฟีเจอร์ LocalStorage (ใช้ได้กับ Android 5.0 ขึ้นไป) PlatformStorage (ใช้ได้กับ Android 12 ขึ้นไป) PlayServicesStorage (ใช้ได้กับ Android 5.0 ขึ้นไป)
การค้นหาข้อความแบบเต็มอย่างมีประสิทธิภาพ
การรองรับหลายภาษา
ไฟล์ไบนารีมีขนาดเล็กลง
การแชร์ข้อมูลระหว่างแอปพลิเคชัน
ความสามารถในการแสดงข้อมูลบนแพลตฟอร์ม UI ของระบบ
จัดทำดัชนีเอกสารได้ไม่จำกัดจำนวนและขนาด
การดำเนินการที่เร็วขึ้นโดยไม่มีเวลาในการตอบสนองเพิ่มเติมของ Binder

มีข้อควรพิจารณาเพิ่มเติมที่ควรพิจารณาเมื่อเลือกระหว่าง LocalStorage กับ PlatformStorage เนื่องจาก PlatformStorage แพ็กเกจ API ของ Jetpack ไว้ในบริการระบบ AppSearch ผลกระทบต่อขนาด APK จึงมีน้อยมากเมื่อเทียบกับการใช้ LocalStorage อย่างไรก็ตาม การดำเนินการของ AppSearch จะเกิดความล่าช้าเพิ่มเติมของ Binder เมื่อเรียกใช้บริการระบบ AppSearch ด้วย เมื่อใช้ PlatformStorage AppSearch จะจำกัดจำนวนเอกสารและขนาดของเอกสารที่แอปพลิเคชันจัดทำดัชนีได้ เพื่อให้ได้ดัชนีกลางที่มีประสิทธิภาพ PlayServicesStorage มีข้อจำกัดเช่นเดียวกับ PlatformStorage และใช้ได้เฉพาะในอุปกรณ์ที่มีบริการ Google Play

เริ่มต้นใช้งาน AppSearch

ตัวอย่างในส่วนนี้แสดงวิธีใช้ AppSearch API เพื่อผสานรวมกับแอปพลิเคชันการจดบันทึกสมมติ

เขียนคลาสเอกสาร

ขั้นตอนแรกในการผสานรวมกับ AppSearch คือเขียนคลาสเอกสารเพื่ออธิบายข้อมูลที่จะใช้แทรกลงในฐานข้อมูล ทำเครื่องหมายคลาสเป็นคลาสเอกสารโดยใช้คำอธิบายประกอบ @Document คุณสามารถใช้อินสแตนซ์ของคลาสเอกสารเพื่อใส่เอกสารและดึงเอกสารจากฐานข้อมูลได้

โค้ดต่อไปนี้กำหนดคลาสเอกสารโน้ตที่มีช่องที่มีคำอธิบายประกอบ @Document.StringProperty สำหรับจัดทำดัชนีข้อความของออบเจ็กต์โน้ต

Kotlin

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

Java

@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 และรับ ListenableFuture สำหรับ AppSearchSession ซึ่งแสดงการเชื่อมต่อกับฐานข้อมูลและให้บริการ API สําหรับการดําเนินการกับฐานข้อมูล

Kotlin

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

Java

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

ตั้งค่าสคีมา

คุณต้องตั้งค่าสคีมาก่อนจึงจะใส่เอกสารและเรียกข้อมูลเอกสารจากฐานข้อมูลได้ สคีมาฐานข้อมูลประกอบด้วย Structured Data ประเภทต่างๆ ซึ่งเรียกว่า "ประเภทสคีมา" โค้ดต่อไปนี้จะตั้งค่าสคีมาโดยระบุคลาสเอกสารเป็นประเภทสคีมา

Kotlin

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

Java

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

ใส่เอกสารในฐานข้อมูล

เมื่อเพิ่มสคีมาประเภทหนึ่งแล้ว คุณจะเพิ่มเอกสารประเภทนั้นลงในฐานข้อมูลได้ โค้ดต่อไปนี้จะสร้างเอกสารประเภทสคีมา Note โดยใช้เครื่องมือสร้างคลาสเอกสาร Note ซึ่งจะตั้งค่าเนมสเปซเอกสาร user1 เพื่อแสดงผู้ใช้แบบสุ่มของตัวอย่างนี้ จากนั้นระบบจะแทรกเอกสารลงในฐานข้อมูลและแนบ Listener เพื่อประมวลผลผลลัพธ์ของการดำเนินการ Put

Kotlin

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
)

Java

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

คุณสามารถค้นหาเอกสารที่จัดทําดัชนีโดยใช้การดำเนินการค้นหาที่กล่าวถึงในส่วนนี้ได้ โค้ดต่อไปนี้จะค้นหาคำว่า "fruit" ในฐานข้อมูลสำหรับเอกสารที่เป็นของเนมสเปซ user1

Kotlin

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
)

Java

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

การค้นหาจะแสดงอินสแตนซ์ SearchResults ซึ่งให้สิทธิ์เข้าถึงหน้าออบเจ็กต์ SearchResult SearchResult แต่ละรายการจะเก็บ GenericDocument ที่ตรงกัน ซึ่งเป็นรูปแบบทั่วไปของเอกสารที่ระบบจะแปลงเอกสารทั้งหมดเป็น โค้ดต่อไปนี้จะรับหน้าแรกของผลการค้นหาและแปลงผลลัพธ์กลับเป็นเอกสาร Note

Kotlin

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
)

Java

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 เอกสารออกจากฐานข้อมูลตามรหัส

Kotlin

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

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

Java

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

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

บันทึกลงในดิสก์

การอัปเดตฐานข้อมูลควรบันทึกลงในดิสก์เป็นระยะโดยการเรียกใช้ requestFlush() โค้ดต่อไปนี้เรียก requestFlush() ด้วย Listener เพื่อระบุว่าการเรียกใช้สำเร็จหรือไม่

Kotlin

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)

Java

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 ควรปิดเมื่อแอปพลิเคชันจะไม่เรียกใช้การดำเนินการใดๆ กับฐานข้อมูลอีกต่อไป โค้ดต่อไปนี้จะปิดเซสชัน AppSearch ที่เปิดไว้ก่อนหน้านี้และเก็บข้อมูลอัปเดตทั้งหมดไว้ในดิสก์

Kotlin

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

Java

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

แหล่งข้อมูลเพิ่มเติม

ดูข้อมูลเพิ่มเติมเกี่ยวกับ AppSearch ได้ที่แหล่งข้อมูลเพิ่มเติมต่อไปนี้

ตัวอย่าง

  • ตัวอย่าง AppSearch ของ Android (Kotlin) ซึ่งเป็นแอปจดบันทึกที่ใช้ AppSearch เพื่อจัดทำดัชนีโน้ตของผู้ใช้และอนุญาตให้ผู้ใช้ค้นหาโน้ตได้

แสดงความคิดเห็น

แชร์ความคิดเห็นและไอเดียกับเราผ่านแหล่งข้อมูลต่อไปนี้

เครื่องมือติดตามปัญหา

รายงานข้อบกพร่องเพื่อให้เราแก้ไขได้