Men of the Mass รายการค้นหา php i ค้นหาสดบน Bitrix ตัวอย่างการใช้งาน การสร้างฐานข้อมูล

โดย อิบราฮิม ดิอัลโล

เผยแพร่เมื่อ 2 กรกฎาคม 2014 ~ อ่าน 16 นาที

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

หากคุณกำลังรีบและเพียงต้องการให้เว็บไซต์ของคุณสามารถค้นหาได้ ให้ทำอย่างที่ฉันเคยทำมาก่อน ลองใช้ Google

// ในไฟล์ search.php $term = isset($_GET["query"])?$_GET["query"]: ""; $term = urlencode($term); $เว็บไซต์ = urlencode("www.yourwebsite.com"); $redirect = "https://www.google.com/search?q=site%3A($website)+($term)"; header("ตำแหน่ง: $redirect"); ออก;

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

โซลูชันการค้นหาแบบโฮมเมด

ก่อนที่เราจะไปไกลกว่านี้ ลองใช้ช่องค้นหาในบล็อกนี้ก่อน มันใช้กระบวนการเดียวกับที่ฉันจะอธิบายด้านล่าง หากคุณรู้สึกว่านี่คือสิ่งที่คุณต้องการโปรดอ่านต่อ

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

หมายเหตุ: หากคุณมีโพสต์ในบล็อก 5,000 โพสต์ คุณยังสบายดี -

เราจะนำโครงสร้างของบล็อกนี้เป็นข้อมูลอ้างอิง แต่ละโพสต์ในบล็อกมี:

  • ชื่อ p_title
  • URL p_url
  • สรุป p_summary
  • เนื้อหาโพสต์ p_content
  • และหมวดหมู่อาหาร Category.tagname

เราจะให้คะแนนสำหรับทุกช่องที่ตรงกับคำค้นหาของเรา คะแนนจะขึ้นอยู่กับความสำคัญของการแข่งขัน:

// พบคำที่ตรงกันทุกประการในหัวข้อ $scoreFullTitle = 6; // จับคู่ชื่อในส่วน $scoreTitleKeyword = 5; // พบคำที่ตรงกันทุกประการในสรุป $scoreFullSummary = 5; // จับคู่ข้อมูลสรุปในส่วน $scoreSummaryKeyword = 4; // พบคำที่ตรงกันทุกประการในเนื้อหา $scoreFullDocument = 4; // จับคู่เอกสารในส่วน $scoreDocumentKeyword = 3; // จับคู่หมวดหมู่ $scoreCategoryKeyword = 2; // ตรงกับ url $scoreUrlKeyword = 1;

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

// ลบคำที่ไม่จำเป็นออกจากคำค้นหาแล้วส่งคืนเป็นฟังก์ชันอาร์เรย์ filterSearchKeys($query)( $query = trim(preg_replace("/(\s+)+/", " ", $query)); $words = array(); // ขยายรายการนี้ด้วยคำพูดของคุณ $list = array("in", "it", "a", "ของ", "หรือ", "คุณ", "เขา", "ฉัน", "พวกเรา", "พวกเขา", "ถึง", "แต่", "นี้", "เหล่านั้น", "แล้ว"); ", $query) เป็น $key)( if (in_array($key, $list))( Continue; ) $words = $key; if ($c >= 15)( break; ) $c++ ; ) ส่งคืน $words ; ) // จำกัดจำนวนคำของฟังก์ชัน LimitChars($query, $limit = 200)( return substr($query, 0,$limit); )

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

หมายเหตุ: ฉันจะไม่แสดงวิธีเชื่อมต่อกับฐานข้อมูล MySQL หากคุณกำลังประสบปัญหาในการเชื่อมต่อกับฐานข้อมูลอย่างมีประสิทธิภาพ ฉันแนะนำให้อ่านสิ่งนี้

เรามาสร้างโครงสร้างให้กับฟังก์ชันของเราก่อน หมายเหตุ ฉันทิ้งตัวยึดตำแหน่งไว้เพื่อให้เราสามารถนำส่วนต่างๆ ไปใช้แยกกันได้

ฟังก์ชั่น search($query)( $query = trim($query); if (mb_strlen($query)===0)( // ไม่ต้องค้นหาว่างใช่ไหม return false; ) $query = LimitChars($query) ; // การชั่งน้ำหนักคะแนน $scoreFullTitle = 5; $scoreFullKeyword = 2; = filterSearchKeys( $query); $escQuery = DB::escape($query); = array(); $docSQL = array(); (); $urlSQL = array(); /** การจับคู่รายการทั้งหมด PLACE HOLDER **/ /** การจับคู่คีย์เวิร์ด PLACE HOLDER **/ $sql = "SELECT p. p_id,p.p_title,p.p_date_published,p. p_url, p.p_summary,p.p_content,p.thumbnail, ((-- คะแนนหัวข้อ ".implode(" + ", $titleSQL)")+ (-- สรุป ".implode(" + ", $sumSQL) .")+ (-- document ".implode(" + ", $docSQL).")+ (-- tag/category ".implode(" + ", $ categorySQL).")+ (-- url ". implode(" + ", $urlSQL).")) เป็นความเกี่ยวข้องจากโพสต์ p WHERE p.status = "published" มีความเกี่ยวข้อง >

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

ตรงกับเหตุการณ์ทั้งหมด

เราต้องแน่ใจว่าเรามีคำหลักบางคำก่อน จากนั้นจึงเพิ่มข้อความค้นหาของเรา

ถ้า (นับ($คำหลัก) > 1)( $titleSQL = "if (p_title LIKE "%".$escQuery."%",($scoreFullTitle),0)"; $sumSQL = "if (p_summary LIKE "%" .$escQuery"%",($scoreFullSummary),0)"; $docSQL = "if (p_content LIKE "%".$escQuery."%",($scoreFullDocument),0)"; )

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

การจับคู่คำหลักที่เกิดขึ้น

เราวนดูคำหลักทั้งหมดและตรวจสอบว่าคำหลักตรงกับช่องใดหรือไม่ สำหรับการจับคู่หมวดหมู่ ฉันใช้ข้อความค้นหาย่อยเนื่องจากโพสต์สามารถมีได้หลายหมวดหมู่

Foreach($keywords as $key)( $titleSQL = "if (p_title LIKE "%".DB::escape($key)."%",($scoreTitleKeyword),0)"; $sumSQL = "if (p_summary) LIKE "%".DB::escape($key)"%",($scoreSummaryKeyword),0)"; $docSQL = "if (p_content LIKE "%".DB::escape($key)"% ",($scoreDocumentKeyword),0)"; $urlSQL = "if (p_url LIKE "%".DB::escape($key)."%",($scoreUrlKeyword),0)"; $categorySQL = "if ((เลือกจำนวน(category.tag_id) จากหมวดหมู่เข้าร่วม post_category ON post_category.tag_id = category.tag_id WHERE post_category.post_id = p.post_id AND category.name = "".DB::escape($key)") > 0 ,($scoreCategoryKeyword),0)"; )

ตามที่ผู้แสดงความคิดเห็นด้านล่างระบุไว้ เราต้องแน่ใจว่าตัวแปรเหล่านี้ไม่ใช่อาร์เรย์ว่าง ไม่เช่นนั้นแบบสอบถามจะล้มเหลว

// เพียงเผื่อว่ามันว่างเปล่า ให้เพิ่ม 0 if (empty($titleSQL))( $titleSQL = 0; ) if (empty($sumSQL))( $sumSQL = 0; ) if (empty($docSQL))( $docSQL = 0; ) if (empty($urlSQL))( $urlSQL = 0; ) if (empty($tagSQL))( $tagSQL = 0; )

ในตอนท้ายข้อความค้นหาทั้งหมดจะถูกต่อเข้าด้วยกันและรวมเข้าด้วยกันเพื่อกำหนดความเกี่ยวข้องของโพสต์กับข้อความค้นหา

// ลบคำที่ไม่จำเป็นออกจากคำค้นหาแล้วส่งคืนเป็นฟังก์ชันอาร์เรย์ filterSearchKeys($query)( $query = trim(preg_replace("/(\s+)+/", " ", $query)); $words = array(); // ขยายรายการนี้ด้วยคำพูดของคุณ $list = array("in", "it", "a", "ของ", "หรือ", "คุณ", "เขา", "ฉัน", "พวกเรา", "พวกเขา", "ถึง", "แต่", "นี้", "เหล่านั้น", "แล้ว"); ", $query) เป็น $key)( if (in_array($key, $list))( Continue; ) $words = $key; if ($c >= 15)( break; ) $c++ ; ) ส่งคืน $words ; ) // จำกัดจำนวนคำของฟังก์ชัน LimitChars($query, $limit = 200)( return substr($query, 0,$limit); ) function search($query)( $query = trim ($query); if (mb_strlen($query)===0)( // ไม่จำเป็นต้องค้นหาว่างใช่ไหม return false; ) $query = LimitChars($query); // การชั่งน้ำหนักคะแนน $scoreFullTitle = 6 $; ScoreTitleKeyword = 5; คะแนนเต็มคำหลัก = 4; ")+ (-- สรุป ".implode(" + ", $sumSQL).")+ (-- เอกสาร ".implode(" + ", $docSQL).")+ (-- แท็ก/หมวดหมู่ ".implode (" + ", $categorySQL).")+ (-- url ".implode(" + ", $urlSQL).")) เป็นความเกี่ยวข้องจากโพสต์ p WHERE p.status = "published" มีความเกี่ยวข้อง > 0 เรียงตาม DESC ที่เกี่ยวข้อง, p.page_views DESC จำกัด 25";

ตอนนี้ไฟล์ search.php ของคุณสามารถมีลักษณะดังนี้:

$term = isset($_GET["query"])?$_GET["query"]: ""; $search_results = ค้นหา($เทอม); if (!$search_results) ( echo "No results"; exit; ) // พิมพ์หน้าที่มีผลลัพธ์ที่นี่

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

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

หากคุณต้องการเห็นการทำงานของอัลกอริธึมการค้นหา ให้ลองค้นหาบทความในช่องค้นหาที่ด้านบนของหน้า ฉันได้เพิ่มคุณสมบัติพิเศษ เช่น การคืนส่วนที่พบรายการที่ตรงกันในข้อความ อย่าลังเลที่จะเพิ่มคุณสมบัติให้กับคุณ

คุณชอบบทความนี้หรือไม่? คุณสามารถสมัครสมาชิกเพื่ออ่านสิ่งที่ยอดเยี่ยมเพิ่มเติม

-

ในบันทึกที่เกี่ยวข้อง นี่คือบทความที่น่าสนใจบางส่วน

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

Vim เป็นโปรแกรมแก้ไขข้อความที่ฉันชื่นชอบบนเทอร์มินัล หลังจากเล่นกับ nano และ emacs มาได้สักระยะ ในที่สุดฉันก็ตัดสินใจเลือก vim เพื่อความเรียบง่ายของมัน (โปรดอยู่กับฉันด้วย) แม้ว่าจะสามารถปรับแต่งและใช้งานได้เหมือนกับ IDE ทั้งหมด แต่ฉันใช้เพื่อแก้ไขไฟล์บนเซิร์ฟเวอร์ของฉันเป็นส่วนใหญ่และทำการเปลี่ยนแปลงเล็กๆ น้อยๆ แต่สำคัญ อย่าเข้าสู่สงครามของบรรณาธิการแล้วเริ่มต้นกันเลย

ความคิดเห็น(45)

ซาริล 12 สิงหาคม 2558:

เอียนมุสตาฟา 26 กันยายน 2558:

ปล้น 29 กันยายน 2558:

ยอมรับ 11 กุมภาพันธ์ 2559:

อีวาน เวเนดิคตอฟ 9 เมษายน 2559

งานหลัก:

  • ใช้การค้นหาในลักษณะที่หลังจากป้อนคำค้นหาลงในบรรทัดแล้ว ผลการค้นหาจะปรากฏใต้บรรทัดนี้
  • การขอผลลัพธ์ควรเกิดขึ้นหลังจากป้อนคำค้นหาแล้วเท่านั้น

เอาล่ะ ไปกันเลย!

เค้าโครงโดยประมาณของบล็อกด้วยบรรทัดค้นหาและชื่อเล่น div ที่เราจะเพิ่มผลการค้นหา:

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

// ตัดการค้นหาออก: $APPLICATION->AddHeadScript("/search/ajax_search.js"); $แอปพลิเคชัน->AddHeadScript("/search/jquery.mCustomScrollbar.js"); $APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH . "/css/ajax_search.css"); $APPLICATION->SetAdditionalCSS(SITE_TEMPLATE_PATH . "/css/jquery.mCustomScrollbar.min.css");

ตอนนี้เรามาดูกันว่ามีอะไรอยู่ใน ajax_search.js ของเราบ้าง:

ฟังก์ชั่น get_result ()( //ล้างผลการค้นหา $("#search_result").html(""); // ยังไม่ได้รับผลการค้นหา - แสดงตัวโหลดล่วงหน้า $("#search_result").append(" "); $.ajax(( ประเภท: "POST", url: "/search/ajax_search.php", ข้อมูล: "q="+q, dataType: "json", ความสำเร็จ: function(json)( //clear ตัวโหลดล่วงหน้า $("#search_result").html(""); $("#search_result").append(""); // เพิ่มแต่ละองค์ประกอบของอาร์เรย์ json ภายใน div ด้วย class="live-search" ( รูปแบบที่คุณสามารถใช้ของคุณ) $.each(json, function(index, element) ( $("#search_result").find(".live-search").append(""+element.TITLE+""+element. BODY_FORMATED+" "); //console.log (element.BODY_FORMATED); )); // การเลื่อนสไตล์ $(".live-search").mCustomScrollbar(( scrollInertia: 500 ) )); 0; var q = ""; $(document).ready(function() ( $("#q").keyup(function() ( q = this.value; clearTimeout(timer); timer = setTimeout(get_result, 1000) ; )); $("#reset_live_search").click(function() ( $("#search_result").html(""); ));

ฟังก์ชัน keyup เราเรียกฟังก์ชัน get_result() ซึ่งจริงๆ แล้วเติมชื่อเล่น div ด้วย id="search_result" ใน Ajax

mCustomScrollbar เป็นเพียงการเรียกสไตล์ (คุณสามารถปิดได้)

เราได้รับข้อมูลจาก /search/ajax_search.php ในรูปแบบ JSON

ทุกอย่างชัดเจนด้วยองค์ประกอบ JS ตอนนี้เรามาดูกันว่าเกิดอะไรขึ้นใน ajax_search.php:

ในกรณีนี้ การค้นหาจะดำเนินการโดยวิธีการค้นหาของคลาส Bitrix CSearch ใน PARAM2 เราเขียนว่าเราต้องการบล็อกข้อมูลใด เราใส่ผลการค้นหาลงในอาร์เรย์ $result โปรดทราบว่า $res['ITEM_ID'] สามารถมีรายการหรือส่วนก็ได้ ขึ้นอยู่กับสิ่งที่เราพบ ใน $result_item['BODY_FORMATED'] เราผลักชื่อเรื่องของส่วนหรือข้อความบางส่วนจากองค์ประกอบบล็อกข้อมูลที่พบ

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

ขั้นตอนแรก. ฐานข้อมูล MySQL

การสร้างฐานข้อมูล ค้นหา_liteมีสองตาราง ข่าว- ข่าวและ ว่าง- ตำแหน่งงานว่าง

กำหนดสิทธิ์:

เข้าสู่ระบบ - " ราก",

รหัสผ่าน - "",

เจ้าภาพ - " โลคัลโฮสต์".

ทิ้งตารางข่าวซะ

โครงสร้างตารางสำหรับตาราง `ข่าว` -- สร้างตารางหากไม่มี `ข่าว` (`id` int(2) ไม่เป็นโมฆะ, `ชื่อ` varchar(255) ไม่เป็นโมฆะ, `ข้อความ` ข้อความไม่เป็นโมฆะ, คีย์หลัก (`id `)) ENGINE=ชุดคำสั่งเริ่มต้นของ MyISAM=cp1251;

Dump table vac - ตำแหน่งงานว่าง

โครงสร้างตารางสำหรับตาราง `vac` -- สร้างตารางหากไม่มี `vac` (`id` int(2) ไม่เป็นโมฆะ AUTO_INCREMENT, `ชื่อ` varchar(255) ไม่เป็นโมฆะ, `ข้อความ` ข้อความไม่เป็นโมฆะ, คีย์หลัก (` id`)) เครื่องยนต์ = ค่าเริ่มต้นของ MyISAM CHARSET = cp1251 AUTO_INCREMENT = 3 ;

ขั้นตอนที่สอง HTML และ PHP

การเชื่อมต่อกับฐานข้อมูล ตั้งเงื่อนไขให้กับตัวแปร $ ค้นหาซึ่งไม่ได้ป้อนคำค้นหาหรือมีอักขระน้อยกว่า 4 ตัว เรายังตรวจสอบเครื่องหมายทับและตัดทอนตัวแปรด้วย เราสร้างสองแบบสอบถามที่ค้นหาสองตารางในฐานข้อมูล ข่าวและ ว่างตามเงื่อนไขการค้นหาตามฟิลด์ ข้อความ- (คุณสามารถเลือกจำนวนตารางที่ต้องการสำหรับการค้นหาได้แล้ว เช่น คุณจะมีตาราง บทเรียน, วัสดุ, บทความฯลฯ คุณยังสามารถเปลี่ยนเงื่อนไขการค้นหาแทนฟิลด์ได้ ข้อความคุณสามารถเลือกฟิลด์ได้ ชื่อหรือช่องอื่น) จากนั้นเราจะระบุจำนวนอักขระในข้อความเมื่อแสดงการค้นหาในตัวแปร $สัญลักษณ์ถ้าอยู่ในตาราง ข่าวและ ว่างไม่พบสิ่งใดในการค้นหา เราแสดงข้อความ หากพบให้แสดงข้อมูลจากสองตาราง ข่าวและ ว่างสำหรับคำค้นหาที่กำหนด