สร้างอินเทอร์เฟซการค้นหาด้วย Query API

Query API มีเมธอดค้นหาและแนะนำสำหรับการสร้างอินเทอร์เฟซการค้นหา หรือการฝังผลการค้นหาในแอปพลิเคชัน

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

สร้างอินเทอร์เฟซการค้นหา

การสร้างอินเทอร์เฟซการค้นหาที่เรียบง่ายต้องทำหลายขั้นตอน ดังนี้

  1. กำหนดค่าแอปพลิเคชันการค้นหา
  2. สร้างข้อมูลเข้าสู่ระบบ OAuth สำหรับแอปพลิเคชัน
  3. ค้นหาดัชนี
  4. แสดงผลการค้นหา

คุณสามารถปรับปรุงอินเทอร์เฟซการค้นหาเพิ่มเติมได้ด้วยฟีเจอร์ต่างๆ เช่น การแบ่งหน้า การจัดเรียง การกรอง Facet และการเติมข้อความอัตโนมัติ

กำหนดค่าแอปพลิเคชันการค้นหา

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

ดูข้อมูลเพิ่มเติมเกี่ยวกับแอปพลิเคชันการค้นหาได้ที่ปรับแต่งประสบการณ์การค้นหาใน Cloud Search

สร้างข้อมูลเข้าสู่ระบบ OAuth สำหรับแอปพลิเคชัน

นอกเหนือจากขั้นตอนในกำหนดค่าการเข้าถึง Google Cloud Search API แล้ว คุณยังต้องสร้างข้อมูลเข้าสู่ระบบ OAuth สำหรับเว็บแอปพลิเคชันด้วย ประเภท ของข้อมูลเข้าสู่ระบบที่คุณสร้างจะขึ้นอยู่กับบริบทที่ใช้ API

ใช้ข้อมูลเข้าสู่ระบบเพื่อขอการให้สิทธิ์ในนามของผู้ใช้ ใช้ ขอบเขต https://www.googleapis.com/auth/cloud_search.query เมื่อขอ การให้สิทธิ์

ดูข้อมูลเพิ่มเติมเกี่ยวกับตัวเลือก OAuth และไลบรารีของไคลเอ็นต์ได้ที่[Google Identity Platform](https://developers.google.com/identity/choose-auth{: .external target="_blank"})

ค้นหาดัชนี

ใช้วิธี search เพื่อทำการค้นหาในดัชนี

ทุกคำขอต้องมีข้อมูล 2 อย่าง ได้แก่ ข้อความ query เพื่อจับคู่กับรายการ และsearchApplicationIdที่ระบุรหัสสำหรับแอปพลิเคชันค้นหาที่จะใช้

ข้อมูลโค้ดต่อไปนี้แสดงการค้นหาแหล่งข้อมูลภาพยนตร์สำหรับภาพยนตร์เรื่อง Titanic

{
  "query": "titanic",
  "requestOptions": {
    "searchApplicationId": "searchapplications/<search_app_id>"
  },
}

แสดงผลการค้นหา

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

จัดการผลการค้นหาเพิ่มเติม

โดยค่าเริ่มต้น Cloud Search จะแสดงผลการค้นหาเพิ่มเติมเมื่อมีผลการค้นหาไม่เพียงพอสำหรับคำค้นหาของผู้ใช้ ฟิลด์ queryInterpretation ในการตอบกลับจะระบุเวลาที่ระบบแสดงผลการค้นหาเสริม หากระบบแสดงเฉพาะผลการค้นหาเพิ่มเติม ระบบจะตั้งค่า InterpretationType เป็น REPLACE หากระบบแสดงผลลัพธ์บางรายการสำหรับคำค้นหาเดิมพร้อมกับผลลัพธ์เสริม ระบบจะตั้งค่า InterpretationType เป็น BLEND ไม่ว่าจะเป็นกรณีใดก็ตาม QueryInterpretation.Reason = NOT_ENOUGH_RESULTS_FOUND_FOR_USER_QUERY

เมื่อระบบแสดงผลการค้นหาเสริมบางรายการ ให้พิจารณาใส่ข้อความ เพื่อระบุว่าระบบแสดงผลการค้นหาเสริม เช่น ในกรณีของ a REPLACE คุณอาจแสดงสตริง "การค้นหาข้อความค้นหาเดิมของคุณไม่ตรงกับผลลัพธ์ใดๆ กำลังแสดงผลการค้นหาสำหรับคำค้นหาที่คล้ายกัน"

ในกรณีของ BLEND คุณอาจแสดงสตริง "การค้นหาคำค้นหาเดิมของคุณไม่ตรงกับผลลัพธ์มากพอ รวมผลการค้นหาสำหรับคำค้นหาที่คล้ายกัน"

จัดการผลการค้นหาบุคคล

Cloud Search จะแสดง "ผลการค้นหาเกี่ยวกับบุคคล" 2 ประเภท ได้แก่ เอกสารที่เกี่ยวข้องกับบุคคลที่มีชื่ออยู่ในคำค้นหา และข้อมูลพนักงานของบุคคลที่มีชื่ออยู่ในคำค้นหา ผลการค้นหาประเภทหลังเป็นฟังก์ชันของฟีเจอร์การค้นหาบุคคลของ Cloud Search และผลการค้นหาสำหรับคำค้นหาดังกล่าวจะอยู่ในฟิลด์ structuredResults ของการตอบกลับ API ของคำค้นหา

{
  "results": [...],
  "structuredResults": [{
    "person": {...}
  }]
}

การจับคู่ผู้ใต้บังคับบัญชา

การจับคู่ผู้รายงานโดยตรงเป็นฟีเจอร์การค้นหาบุคคลของ Cloud Search ซึ่งช่วยให้ผู้ใช้เห็นผู้รายงานโดยตรงของบุคคลในองค์กร ผลลัพธ์จะแสดงในช่องstructuredResults

สำหรับคำค้นหาเกี่ยวกับผู้จัดการหรือผู้ใต้บังคับบัญชาของบุคคล คำตอบจะมี assistCardProtoHolder ภายใน structuredResults assistCardProtoHolder มีฟิลด์ชื่อ cardType ซึ่งจะเท่ากับ RELATED_PEOPLE_ANSWER_CARD assistCardProtoHolder มีการ์ด ชื่อ relatedPeopleAnswerCard ซึ่งมีการตอบกลับจริง โดยมีsubject (บุคคลที่รวมอยู่ในคำค้นหา) และrelatedPeople ซึ่งเป็นชุดบุคคลที่เกี่ยวข้องกับเรื่อง ฟิลด์ relationType จะแสดงค่า MANAGER หรือ DIRECT_REPORTS

โค้ดต่อไปนี้แสดงตัวอย่างการตอบกลับสำหรับการค้นหาการจับคู่ผู้รายงานโดยตรง

{
  "results": [],
  "structuredResults": [{
    "assistCardProtoHolder": {
      "extensions": {
        "@type": "type.googleapis.com/enterprise.topaz.sidekick.AssistCardProto",
        "cardMetadata": {
          "cardCategory": "ANSWER"
        },
        "cardType": "RELATED_PEOPLE_ANSWER_CARD",
        "relatedPeopleAnswerCard": {
          "subject": {
            "email": "AdamStanford@psincs-test01.newjnj.com",
            "displayName": "Adam Stanford"
            "manager": {
              "email": "simonsais@psincs-test01.newjnj.com"
            }
          },
          "relatedPeople": [{
            "email": "EdgarMountainRamirez@psincs-test01.newjnj.com",
            "displayName": "Edgar Mountain Ramirez"
          }, {
            "email": "FranciscoJoseMartinez@psincs-test01.newjnj.com",
            "displayName": "Francisco Jose Martinez"
          }],
          "relationType": "DIRECT_REPORTS",
        }
      }
    }
  }]
}

ปิดการเพิ่มประสิทธิภาพ รวมถึงผลการค้นหาเสริม

โดยค่าเริ่มต้น ระบบจะเปิดใช้การเพิ่มประสิทธิภาพ เช่น ผลการค้นหาเพิ่มเติม อย่างไรก็ตาม คุณสามารถปิดการเพิ่มประสิทธิภาพทั้งหมดหรือเฉพาะผลการค้นหาเสริมได้ทั้งในระดับแอปพลิเคชันค้นหาและระดับการค้นหา โดยทำดังนี้

  • หากต้องการปิดการเพิ่มประสิทธิภาพทั้งหมดที่ระดับแอปพลิเคชันการค้นหา ซึ่งรวมถึง ผลการค้นหาเสริม คำพ้อง และการแก้ไขตัวสะกด ให้ตั้งค่า QueryInterpretationConfig.force_verbatim_mode เป็น true ในแอปพลิเคชันการค้นหา

  • หากต้องการปิดการเพิ่มประสิทธิภาพทั้งหมดที่ระดับคำค้นหา ซึ่งรวมถึง ผลการค้นหาเพิ่มเติม คำพ้อง และการแก้ไขตัวสะกด ให้ตั้งค่า QueryInterpretationOptions.enableVerbatimMode เป็น true ในคำค้นหา

  • หากต้องการปิดผลการค้นหาเพิ่มเติมที่ระดับแอปพลิเคชันการค้นหา ให้ตั้งค่า QueryInterpretationOptions.forceDisableSupplementalResults เป็น true ในคำค้นหา

  • หากต้องการปิดผลการค้นหาเพิ่มเติมที่ระดับคำค้นหา ให้ตั้งค่า QueryInterpretationOptions.disableSupplementalResults เป็น true ในคำค้นหา

ไฮไลต์ตัวอย่าง

สำหรับรายการที่ส่งคืนซึ่งมีข้อความที่จัดทำดัชนีหรือเนื้อหา HTML ระบบจะแสดงตัวอย่าง ของเนื้อหา เนื้อหานี้ช่วยให้ผู้ใช้พิจารณา ความเกี่ยวข้องของรายการที่แสดง

หากมีคำค้นหาในข้อมูลโค้ด ระบบจะแสดงผลช่วงที่ตรงกันอย่างน้อย 1 ช่วงซึ่งระบุตำแหน่งของคำด้วย

ใช้ matchRanges เพื่อไฮไลต์ข้อความที่ตรงกันเมื่อแสดงผล ลัพธ์ ตัวอย่าง JavaScript ต่อไปนี้จะแปลงข้อมูลโค้ดเป็น มาร์กอัป HTML โดยแต่ละช่วงที่ตรงกันจะอยู่ในแท็ก <span>

function highlightSnippet(snippet) {
  let text = snippet.snippet;
  let formattedText = text;
  if (snippet.matchRanges) {
    let parts = [];
    let index = 0;
    for (let match of snippet.matchRanges) {
      let start = match.start || 0; // Default to 0 if omitted
      let end = match.end;
      if (index < start) { // Include any leading text before/between ranges
        parts.push(text.slice(index, start));
      }
      parts.push('<span class="highlight">');
      parts.push(text.slice(start, end));
      parts.push('</span>');
      index = end;
    }
    parts.push(text.slice(index)); // Include any trailing text after last range
    formattedText = parts.join('');
  }
  return formattedText;
}

จากข้อมูลโค้ดต่อไปนี้

{
  "snippet": "This is an example snippet...",
  "matchRanges": [
    {
      "start": 11,
      "end": 18
    }
  ]
}

สตริง HTML ที่ได้คือ

This is an <span class="highlight">example</span> snippet...

ข้อมูลเมตาที่แสดงผล

ใช้ฟิลด์ metadata เพื่อแสดงข้อมูลเพิ่มเติมเกี่ยวกับสินค้าที่ส่งคืนซึ่งอาจเกี่ยวข้องกับผู้ใช้ ฟิลด์ metadata มี createTime และ updateTime ของสินค้า รวมถึง Structured Data ที่ส่งคืนได้ซึ่งเชื่อมโยง กับสินค้า

หากต้องการแสดง Structured Data ให้ใช้ฟิลด์ displayOptions ฟิลด์ displayOptions มีป้ายกำกับที่แสดงสำหรับประเภทออบเจ็กต์ และชุดของ metalines แต่ละบรรทัดเมตาคืออาร์เรย์ของป้ายกำกับที่แสดงและคู่ค่าตามที่กำหนดค่าไว้ในสคีมา

ดึงข้อมูลผลลัพธ์เพิ่มเติม

หากต้องการดึงผลลัพธ์เพิ่มเติม ให้ตั้งค่าฟิลด์ start ในคำขอเป็นออฟเซ็ตที่ต้องการ คุณปรับขนาด ของแต่ละหน้าได้ด้วยฟิลด์ pageSize

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

จัดเรียงผลลัพธ์

ใช้ฟิลด์ sortOptions เพื่อระบุลำดับของสินค้าที่ส่งคืน ค่า sortOptions คือออบเจ็กต์ที่มี 2 ฟิลด์ ได้แก่

  • operatorName - ตัวดำเนินการสำหรับพร็อพเพอร์ตี้ Structured Data เพื่อจัดเรียงตาม สำหรับพร็อพเพอร์ตี้ที่มีโอเปอเรเตอร์หลายตัว คุณจะจัดเรียงได้โดยใช้โอเปอเรเตอร์ความเท่ากันหลักเท่านั้น
  • sortOrder — ทิศทางการจัดเรียง ซึ่งอาจเป็น ASCENDING หรือ DESCENDING

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

"sortOptions": {
  "operatorName": "priority",
  "sortOrder": "DESCENDING"
}

เพิ่มตัวกรอง

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

หากต้องการเพิ่มตัวกรองในคำขอหรือแอปพลิเคชันค้นหา ให้เพิ่มตัวกรองในช่อง dataSourceRestrictions.filterOptions[]

มี 2 วิธีหลักๆ ในการกรองแหล่งข้อมูลเพิ่มเติม ดังนี้

  • ตัวกรองออบเจ็กต์ผ่านพร็อพเพอร์ตี้ filterOptions[].objectType - จำกัด รายการที่ตรงกันให้เป็นประเภทที่ระบุตามที่กำหนดไว้ในสคีมาที่กำหนดเอง
  • ตัวกรองค่า — จำกัดรายการที่ตรงกันตาม ตัวดำเนินการคำค้นหา และค่าที่ระบุ

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

ในตัวอย่างสคีมาภาพยนตร์ คุณสามารถใช้ข้อจำกัดด้านอายุตาม ผู้ใช้ปัจจุบันและจำกัดภาพยนตร์ที่พร้อมให้บริการตามการจัดประเภทของ MPAA

{
  "query": "adventure",
  "requestOptions": {
    "searchApplicationId": "<search_app_id>"
  },
  "dataSourceRestrictions": [
    {
      "source": {
        "name": "datasources/<data_source_id>"
      },
      "filterOptions": [
        {
          "objectType": "movie",
          "filter": {
            "compositeFilter": {
              "logicOperator": "AND"
              "subFilters": [
                {
                  "compositeFilter": {
                  "logicOperator": "OR"
                  "subFilters": [
                    {
                      "valueFilter": {
                        "operatorName": "rated",
                        "value": {
                          "stringValue": "G"
                        }
                      }
                    },
                    {
                      "valueFilter": {
                        "operatorName": "rated",
                        "value": {
                          "stringValue": "PG"
                        }
                      }
                    }
                  ]
                }
              ]
            }
          }
        }
      ]
    }
  ]
}

ปรับแต่งผลลัพธ์ด้วยแง่มุม

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

คุณกำหนด Facet ได้ในแอปพลิเคชันการค้นหา และลบล้างได้ด้วยการตั้งค่าในคำค้นหา

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

รูปแบบการโต้ตอบทั่วไปกับแง่มุมมีดังนี้

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

เช่น หากต้องการเปิดใช้การปรับแต่งคำค้นหาภาพยนตร์ตามปีและคะแนน MPAA ให้รวมพร็อพเพอร์ตี้ facetOptions ไว้ในคำค้นหา

"facetOptions": [
  {
    "sourceName": "datasources/<data_source_id>",
    "operatorName": "year"
  },
  {
    "sourceName": "datasources/<data_source_id>",
    "operatorName": "rated"
  }
]

ผลลัพธ์ของ Facet ที่มีช่องที่อิงตามจำนวนเต็ม

นอกจากนี้ คุณยังจัดกลุ่มผลลัพธ์ของคำขอ Facet ด้วยช่องที่อิงตามจำนวนเต็มได้ด้วย เช่น คุณ อาจทำเครื่องหมายพร็อพเพอร์ตี้จำนวนเต็มที่ชื่อ book_pages เป็นพร็อพเพอร์ตี้ที่กรองได้เพื่อปรับแต่ง ผลการค้นหาเกี่ยวกับหนังสือที่มีจำนวนหน้า "100-200" หน้า

เมื่อตั้งค่าสคีมาฟิลด์พร็อพเพอร์ตี้จำนวนเต็ม ให้ตั้งค่า isFacetable เป็น true แล้วเพิ่มตัวเลือกการจัดกลุ่มที่สอดคล้องกันลงใน integerPropertyOptions ซึ่งช่วยให้มั่นใจว่าพร็อพเพอร์ตี้ที่สามารถแบ่งกลุ่มจำนวนเต็มทุกรายการมีการกำหนดตัวเลือกการจัดกลุ่มเริ่มต้น

เมื่อกำหนดตรรกะตัวเลือกการจัดกลุ่ม ให้ระบุอาร์เรย์ของค่าที่เพิ่มขึ้น ซึ่งแสดงถึงช่วง เช่น หากผู้ใช้ปลายทางระบุช่วงเป็น 2, 5, 10, 100 ระบบจะคำนวณแง่มุมสำหรับ <2, [2-5), [5-10), [10-100), >=100

คุณลบล้าง Facet ที่อิงตามจำนวนเต็มได้โดยกำหนดตัวเลือกการจัดกลุ่มเดียวกันกับ facetOptions ในคำขอ หากจำเป็น Cloud Search จะใช้ตัวเลือกการจัดกลุ่มที่กำหนดไว้ใน สคีมาเมื่อทั้งแอปพลิเคชันการค้นหาและคำขอการค้นหาไม่ได้กำหนดตัวเลือก แง่มุมไว้ ข้อมูลประกอบที่กำหนดไว้ในคำค้นหาจะมีลำดับความสำคัญเหนือกว่าข้อมูลประกอบที่กำหนดไว้ ในแอปพลิเคชันการค้นหา และข้อมูลประกอบที่กำหนดไว้ในแอปพลิเคชันการค้นหาจะมี ลำดับความสำคัญเหนือกว่าข้อมูลประกอบที่กำหนดไว้ในสคีมา

จำแนกผลลัพธ์ตามขนาดหรือวันที่ของเอกสาร

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

  • หากต้องการ Facet ตามขนาดเอกสาร ให้ใช้ itemsize และกำหนดตัวเลือกการจัดกลุ่ม
  • หากต้องการแบ่งกลุ่มตามวันที่สร้างเอกสาร ให้ใช้ createddatetimestamp
  • หากต้องการ Facet ตามวันที่แก้ไขเอกสาร ให้ใช้ lastmodified

การตีความที่เก็บข้อมูลประกอบ

พร็อพเพอร์ตี้ facetResults ในคำตอบของคำค้นหาประกอบด้วยคำขอตัวกรองที่ตรงกันทุกประการของผู้ใช้ ในช่อง filter สำหรับแต่ละ bucket

สำหรับ Facet ที่ไม่ได้อิงตามจำนวนเต็ม facetResults จะรวมรายการสำหรับ พร็อพเพอร์ตี้ที่ขอแต่ละรายการ สำหรับแต่ละพร็อพเพอร์ตี้ ระบบจะระบุรายการค่าหรือช่วงที่เรียกว่า buckets ค่าที่เกิดขึ้นบ่อยที่สุดจะปรากฏก่อน

เมื่อผู้ใช้เลือกค่าอย่างน้อย 1 ค่าเพื่อกรอง ให้สร้างการค้นหาใหม่ด้วยตัวกรองที่เลือกและค้นหา API อีกครั้ง

เพิ่มคำแนะนำ

ใช้ suggest API เพื่อให้การเติมข้อความอัตโนมัติสำหรับคำค้นหาตามประวัติการค้นหาส่วนตัว ของผู้ใช้ รวมถึงรายชื่อติดต่อและคลังเอกสารของรายชื่อติดต่อ

เช่น การเรียกใช้ต่อไปนี้จะให้คำแนะนำสำหรับวลีบางส่วน jo

{
  "query": "jo",
  "requestOptions": {
    "searchApplicationId": "<search_app_id>",
    "peoplePhotoOptions": {
      "peoplePhotoUrlSizeInPx": 32
    },
    "timeZone": "America/Denver"
  }
}

จากนั้นคุณจะแสดงคำแนะนำที่ได้ตามความเหมาะสมกับแอปพลิเคชัน ของคุณได้