parsgreen.com
article

جستجو در مطالب سایت با استفاده از MySQL Full-Text و PHP

mysql-fulltext

یکی از قابلیت های خوب MySql که از نسخه 3.23 به بعد به آن اضافه شده، توابع Full-Text است که می تواند جهت کسب نتایج جستجوی سریع و دقیق مورد استفاده قرار گیرد، هرچند برخی از قابلیت های Full-Text یا تمام متن، مربوط به کلمات انگلیسی است ولی توانایی آن برای کلمات فارسی آنقدر هست که بتوانیم بدون مشکل از آن استفاده کنیم و یا لااقل یکی از متدهای جستجو را بر مبنای آن قرار دهیم و در متدهای دیگر به فرض از like استفاده نمائیم؛ در ادامه به توضیح اینکه چرا و چگونه از این قابلیت در کدهای php استفاده کنیم، خواهیم پرداخت.

چرا باید از قابلیت Full-Text به جای like یا در کنار آن استفاده کنیم؟


واقعیت مطلب این است که هر کدام از قابلیت های گفته شده دارای معایب و محاسنی هستند، به عنوان مثال استفاده از like نتایج بیشتری را برمی گرداند ولی در عوض ممکن است نتایجی نامربوط یا تکراری داشته باشد، از طرفی جستجو با متد like در پایگاه داده مخصوصا در جداولی که محتوای زیادی دارند در مقایسه با Full-Text بیشتر زمان می برد؛ از اینها گذشته برخی قابلیت های تمام متن با like بدست نمی آیند.
قابلیت FULLTEXT بر روی ستون هایی از نوع CHAR ,VARCHAR و TEXT و موتور MyISAM ENGINE قابل اعمال است و قبل از ایجاد جدول یا بعد از آن نیز می توانیم به ستون مورد نظر آن را اضافه کنیم:
<?php
mysql_query("CREATE TABLE post(
title VARCHAR(255),
FULLTEXT KEY title(title)) ENGINE=MyISAM ")
?>
برای افزودن این قابلیت بعد از ساختن جدول و ستون، مقادیر sql زیر را پس از تغییرات دلخواه با توجه به تنظیمات ستون مورد نظر اجرا کنید:
ALTER TABLE post ADD FULLTEXT(title);
شیوه جستجو در FULLTEXT بر اساس MATCH() ... AGAINST صورت می گیرد:
SELECT title FROM post
WHERE MATCH (title) AGAINST ('$searchword');
برای جستجو از چند ستون در مقادیر MATCH می توانید از کاما استفاده کنید؛ همچنین می توان از قابلیت امتیاز دهی (score) این تابع نیز جهت چینش نتایج استفاده کنید:
SELECT *, MATCH (title) AGAINST ('$searchword') AS score FROM post
WHERE MATCH (title) AGAINST ('$searchword') ORDER BY score ASC
باید توجه کرد که FULLTEXT برای ایندکس کلمات محدودیتهایی اعمال می کند، از جمله اینکه اگر کلمه ای کمتر از 4 کاراکتر باشد ایندکس نمی شود، اگر کلمه ای در بیش از 50% ردیف ها تکرار شود ایندکس نمی شود، اگر کلمه ای در لیست stopword ها باشد ایندکس نمی شود (البته فعلا فقط مخصوص حروف انگلیسی است) و نهایتا اینکه برای شروع ایندکس کلمات تمام متن، ممکن است نیاز به حداقلی از محتویات باشد.
قابلیتهای دیگر این تابع جستجوی IN BOOLEAN MODE است که امکانات بیشتری در اختیارمان قرار می دهد (اضافه شده به Mysql از Version 4.0.1)، با استفاده از این قابلیت می توانید شمول ابتدا و انتهای یک کلمه را در جستجو تعیین کنید:
SELECT * FROM post WHERE MATCH (title) AGAINST ('+phpcode -htmlcode' IN BOOLEAN MODE);
در مثال بالا اگر کاربر عبارت code را جستجو کند، تیتر های حاوی عبارت phpcode در جستجو خواهند آمد اما تیتر های حاوی عبارت htmlcode در لیست نتایج ظاهر نمی شوند؛ از ویژگی های جستجوی BOOLEAN MODE نادیده گرفتن قانون 50% است.
اما قابلیت تمام متن با امکانی دیگر کامل می شود که Query Expansion نام دارد، همانطور که از معنی Expansion (توسعه) بر می آید نتایج جستجوی معمولی با FullText به دلیل اعمال محدودیت ها و سخت گیری در ایندکس کلمات و یا استفاده از stopword ها، ممکن است بعضا دبرگیرنده همه نتایج نباشد، با افزودن Query Expansion می توانیم موارد معمولی تر را نیز در لیست جستجو نشان دهیم:
SELECT title FROM post
WHERE MATCH (title)
AGAINST ('$searchword' WITH QUERY EXPANSION);
sectionدسته بندی: آموزش کاربردی » MySQL
related مطالب بیشتر:
» ساخت فید آر اس اس (RSS Feed)، با استفاده از php و mysql
» آموزش ساخت پنل ورود و خروج سایت با php و mysql
» آموزش ساخت فرم عضویت در سایت با php و mysql
» آموزش حذف گروهی اطلاعات از MySQL با استفاده از چک باکس
» ایجاد لینک دانلود مدت دار با PHP و MySQL
commentنظرات (۵۹ یادداشت برای این مطلب ارسال شده است)
نویسنده: سروش
زمان: ۱۸:۰۴:۳۰ - تاریخ: ۱۳۹۱/۰۵/۱۰
سلام
استاد اگه بخواهیم از نمره ی بیست به شما امتیاز بدم نمره 5/19 رو میدم مطالب عالیه ولی خیلی مطالب کمه.
پاسخ: 
سلام
نظر لطف شماست، به هر صورت با وجود سایر مشغله های روزمره، ما تمام سعی خود را می کنیم که مطالب مورد نیاز کاربران هر چه زودتر در سایت قرار گیرد، ولی باید توجه نمود که کیفیت را نمی توان فدای کمیت نمود! اکثر مطالب باید چندین بار تست و بررسی شوند و سپس در سایت قرار گیرند.
نویسنده: جواد
زمان: ۱۴:۰۷:۰۶ - تاریخ: ۱۳۹۱/۰۵/۱۸
با سلام
من تو پیداه سازی این کدها چندتا مشکل داشتم
1. چرا وقتی از WITH QUERY EXPANSION استفاده میکنم وقتی دنبال یه کلمه میگردم یه سری کلمات بی ربط با کلمه ای که دنبالش هست در خروجی برام میاره
2. من ومپ سرورم فارسی پوشش نمیده و همه حروف فارسیو به صورت علامت سوال ذخیره میکنه
پاسخ: 
سلام
مشکل اول معمولا به دلیل ذخیره نشدن اطلاعات به حد کافی در دیتابیس است، ظاهرا این امکان بعد از ذخیره میزان خاصی از داده ها عمل می کند، همین طور است در مورد خود FULL TEXT که باید مقادیر ذخیره شده به حد لازم برسد تا کلمات را ایندکس کند.
در مورد مشکل دوم، به احتمال قوی مشکل از استفاده نکردن جداول MySQL شما از یونیکد UTF-8 است، برای سازگاری دیتابیس با زبان فارسی باید موقع ایجاد دیتابیس یونیکد زیر را انتخاب کنید:
utf8_general_ci
و در هنگام ساختن جداول در برنامه خود COLLATE ها را نیز بر روی utf8_general_ci تنظیم کنید، به طور مثال:
mysql_query("ALTER TABLE tb_name
DEFAULT CHARACTER SET utf8
COLLATE utf8_general_ci;")
or die(mysql_error());
در هنگام فراخوانی و گرفتن خروجی از داده ها در صفحات نیز از کد زیر در هدر صفحه استفاده کنید:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
نویسنده: جواد
زمان: ۲۳:۳۴:۵۳ - تاریخ: ۱۳۹۱/۰۵/۱۸
با سلام و تشکر فراوان
در مورد موضوع اولتون ممنون راهنمایی خوبی بود درباره موضوع دوم من این کارایی که گفته بودید و قبلا انجام داده بودم ولی جواب نداده بود، چه مستقیم در خود ومپ سرور اضافه کنی چه از طریق صفحه وب، ولی من فهمیدم که درسته نمیشه خوندش ولی سرچ کار میکنه ولی افسوس برای کلمات انگلیسی اونایی که چهار حرف به بالا هستن و برای فارسی ده تا حرف به بالا ولی من میخوام مثل سایت خودتون کلمات کوچیکم سرچ کنه، اون سری توی سرچ سایتتون نوشتم "به" باز برام تمام کلماتی که به داشتو برام آورد حتی کلمه محاس"به" میخواستم ببینم شما خودتون هم از همین کدا استفاده کردین یا از like استفاده کردین البته ببخشید چنین سوالی پرسیدم شاید نخواسته باشید جواب بدین. اگه یه راهنمایی کوچولو هم بکنین خیلی ممنون میشم
پاسخ: 
سلام
در مورد اینکه برای زبان فارسی حداقل 10 حرف نیاز است، بررسی دقیق نکرده ایم، اما واقعیت این است که تابع full text به تنهایی نمی تواند گزینه مناسبی برای جستجو، مخصوصا به زبان فارسی باشد، چرا که برخی قابلیت های آن تنها با حروف انگلیسی سازگار است، با این حال همانطور که در آموزش یادآور شده ایم، می تواند یکی از گزینه ها باشد، در سیستم جستجوی فعلی «وبگو» نیز از ترکیب تقریبا هوشمندی از like و full text استفاده شده است، اگر کلمه مورد نظر کاربر جزء کلمات ایندکس شده بوده و نتایج به حد نصاب لازم برسد، از full text و در غیر این صورت از like و به صورت داینامیک استفاده می شود.
نویسنده: حیاتی
زمان: ۱۰:۲۲:۴۰ - تاریخ: ۱۳۹۱/۱۰/۱۰
سلام. من هم دقیقا با مشکل آقا جواد روبرو شدم و هر کاری می کردم ومپ سرور حروف فارسی رو به صورت علامت سوال ذخیره میکرد. تمام کارهایی هم که شما گفته بودید انجام دادم درست نشد. تا اینکه بعد از دستور mysql_select_db ...
دستور زیر رو نوشتم:
mysql_query ("SET NAMES 'utf8' ");
همه چی درست شد!
پاسخ: 
سلام
خیلی ممنون از به اشتراک گذاری.
نویسنده: محمد مهدی احمدی
زمان: ۲۳:۳۸:۱۳ - تاریخ: ۱۳۹۲/۰۱/۲۰
سلام
من هم همین مشکل رو داشتم
که برطرفش کردم اولا که حروف فارسی اگر در utf8_general_ci قرار بگیرن حجم دیتا یبس بسیار بسیار کمتر میشه تا اینکه نوع دیگه باشه!
اینجا چند تا راه است که توضیح میدم
1. نوع COLLATE رو utf8_general_ci قرار بدین
2. تو htaccess. دستور
AddDefaultCharset utf-8
رو بنویسید
3. قبل از متغیر های دیتابیس یا کد های اتصال دیتابیس دستور
 mysql_query ("SET NAMES 'utf8' ");
رو تایپ کنید صد در صد مشکلتون برطرف میشه
در اخر هم از سایت وبگو متشکریم بابت آموزش هاش
10 درصد پیشرفت پروژم رو مدیون این سایت هستم مرسی
پاسخ: 
سلام
خیلی ممنون از اینکه مختصر و مفید این موارد را یادآور شدید، مخصوصا مورد htaccess که باعث سازگاری کامل سورس تمام صفحات سایت با UTF-8 می شود.
نویسنده: مجید
زمان: ۱۸:۰۶:۴۷ - تاریخ: ۱۳۹۲/۰۲/۲۶
سلام. من می خواهم با php یک مقدار مثلا "سلام" را از یک فایل ساده txt جستجو کنم و مقدار true یا false را برام بگردونه. میشه کمک کنید؟
پاسخ: 
سلام
انجام این کار به روش های مختلف امکان پذیر است، سریع ترین راه استفاده از تابع strpos است، ابتدا محتوای فایل را با تابع file_get_contents استخراج و سپس با استفاده از تابع strpos وجود یک عبارت را در محتوا بررسی می کنیم، اگر عبارت وجود داشت، تابع مقدار TRUE برمی گرداند و اگر وجود نداشت مقدار FALSE برمی گرداند:
<?php
$file = file_get_contents('file.txt');
if(strpos($file,'سلام') !== FALSE){
echo 'این عبارت وجود دارد';
}
else{
echo 'این عبارت وجود ندارد';
}
?>
نویسنده: بهنام
زمان: ۲۰:۰۶:۴۹ - تاریخ: ۱۳۹۲/۰۴/۰۶
با سلام و تشکر
من از کد شما استفاده کردم ولی این کدم:
mysql_query("ALTER TABLE news ADD FULLTEXT(title)") or die(mysql_error());
این خطا را میدهد:
The used table type doesn't support FULLTEXT indexes
به نظر شما مشکل از کجاست؟
پاسخ: 
سلام
به احتمال زیاد موتور جداول شما بر روی InnoDB قرار دارد، قابلیت FULL TEXT تنها در موتور MyISAM قابل اعمال است، جهت تغییر نوع موتور جدول می توانید پرس و جوی زیر را اجرا کنید:
ALTER TABLE tbl ENGINE = MYISAM
نکته: تغییر موتور جدول ممکن است روی سایر قسمت های برنامه اثر بگذارد، لذا در این زمینه باید آگاهی کامل داشته باشید.
نویسنده: ابوالفضل
زمان: ۲۳:۵۴:۰۸ - تاریخ: ۱۳۹۲/۰۴/۱۰
با سلام این کد جستجوگر سایت من هستش:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<form method="get" action="email.php">
<p>
<input type="text" name="q" size="20">
<input type="submit" value="Search">
</p>
</form>
<?php

if(!isset($_GET["q"]))
die("The Search key word is not set!");

$key = $_GET["q"];
if($key == "")
die("The Search key word must be entered!");
$DbConn = mysql_connect("localhost", "root", "mysql" ) or die(mysql_error());
mysql_select_db("test",$DbConn) or die("Can Not Select DataBase Because: ". mysql_error());
$sql = "SELECT * FROM `text` WHERE `title` LIKE '%".$key ."%';";

$SearchResult = mysql_query($sql) or die(mysql_error(). "SQL: ". $sql);

$TotalResults = mysql_num_rows($SearchResult);

if($TotalResults <= 0)
die("Not found any record for your key word!");

for($i = 0; $i != $TotalResults; $i++ )
{
//<!-- Start of Print Results...

$TextTitle = mysql_result($SearchResult, $i, 1);
$TextBody = mysql_result($SearchResult, $i, 2);

print($TextTitle ." ==> ". $TextBody ."<br /><br />");

//End of Print Results. -->
}

?>
<?php echo $TotalResults; ?>
دو تا مشکل وجود دارد:
1. امکان جستجوی عبارت فارسی نیستش در صورتی که در دیتابیس اطلاعات به فارسی ذخیره می شود
2. اگر نتایج جستجو هزار تا هم باشد در یک صفحه نشان می دهد مثلا من می خوام نتایج جستجو را در صفحات مختلف نمایش بدهد و هر صفحه ده تا نتیجه جستجو بیشتر نباشد
پاسخ: 
سلام
قابلیت LIKE در MySQL از یونیکد utf-8 و به طبع از زبان فارسی پشتیبانی می کند، اما در صورتی که نحوه ذخیره سازی کاراکترها با نحوه فراخوانی یا مطابقت آنها یکی باشد، در اینجا اگر اطلاعات به حروف فارسی در دیتابیس ذخیره شده اند، شاید لازم باشد پرس و جوی زیر را نیز بعد از اتصال به دیتابیس اجرا کنید:
$DbConn = mysql_connect("localhost", "root", "mysql" ) or die(mysql_error());
$SetUTF8 = mysql_query("SET NAMES 'utf8'");
اما برای حل مشکل دوم، آموزش جامعی در خصوص نحوه صفحه بندی محتوا در سایت وجود دارد، از قسمت جستجو عبارت "صفحه بندی" را وارد کنید.
نویسنده: نیلوفر
زمان: ۰۲:۳۳:۴۱ - تاریخ: ۱۳۹۲/۰۴/۲۶
سلام من این دستور رو نوشتم
mysql_query ("SET NAMES 'utf8' ");
و موقع ایجاد دیتابیسم هم
utf8_persian_ci
رو انتخاب کردم وتوی تمام صفحاتم این رو
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
نوشتم حالا وقتی از دیتابیسم یه چیزی میخونم فارسیش درسته اما بقیه صفحه که با html نوشتم عجق و جق میاد چی کار کنم؟؟؟؟؟؟؟ راستی وقتی توی دستور آخری که گفتم به جای
charset=windows-1256 ،charset=utf-8 
رو میذارم بقیه صفحه خوبه اما اطلاعاتی که از جداول دیتابیس میخونه عجق وجقه؟ واقعا ممنون میشم اگه زودتر جواب بدید.
پاسخ: 
سلام
یونیکد دیتابیس را قبل از ذخیره اطلاعات
utf8_general_ci
انتخاب کنید، فایل های خود را با ویرایشگر ++Notepad باز کرده و سپس از قسمت Encoding گزینه Encoding UTF-8 without BOM را انتخاب و فایل خود را مجددا ذخیره نمائید، در صورتی که در htaccess دستوری مربوط به یونیکد وجود دارد، موقتا آن را حذف کنید، با انجام این موارد به احتمال زیاد مشکل حل خواهد شد.
نویسنده: ansherli
زمان: ۰۰:۱۴:۰۹ - تاریخ: ۱۳۹۲/۰۵/۱۶
با سلام
تشکر بابت مطالب و راهنمایی های عالی شما
یه سوال داشتم
من کد جستجوم رو با like نوشتم درستم کار میکنه منتها من توی نشان دادن نتیجه جستجو مشکل دارم
توی سایت شما وقتی مثلا کلمه جستجو رو سرچ می کنیم و نتایج میاد ، عنوان مطلبی که در این صفحه هست میاد به صورت لینک به همین صفحه . آدرس صفحه تغییری نکرده ! یعنی اگر توی مطالب بگردیم به همین صفحه میایم و با جستجو هم همین طور.
من نتایج جستجوم رو توی یه صفحه میارم که با کلیک روی هر کدوم توی یه صفحه دیگه نمایش داده میشه ولی نه اون صفحه ای که دقیقا مطلب مورد نظرم توی سایت هست!
میخوام بدونم چطوری میشه از طریق جستجو دقیقا به همون صفحه ای که یه مطلب قرار گرفته رفت ؟
ممنون میشم راهنماییم کنید
پاسخ: 
سلام
جستجو در دیتابیس ارتباط مستقیمی به نحوه ایجاد لینک ندارد، در واقع این دو مقوله جدا هستند، به فرض اگر یک سیستم یا روش ایجاد لینک داشته باشید که خروجی متشکل از id و title مطالب باشد، در هنگام جستجو در مطالب، می توانید در نتایج باز از همان id و title برای ایجاد لینک استفاده کنید تا نتیجه به یک شکل باشد، به طور مثال پرس و جوی ساخت لینک (دریافت اطلاعات مورد نیاز برای لینک) در حالت عادی:
SELECT id, title FROM tbl
همان پرس و جو برای حالت جستجو:
SELECT id, title FROM tbl WHERE title LIKE '%$search%' OR article LIKE '%$search%'
ملاحظه می کنید که در هر دو پرس و جو id و title که در ساخت لینک کاربرد دارند، فراخوانی می شوند و می توان از آنها استفاده کرد.
نویسنده: مومني موگويي
زمان: ۲۱:۱۹:۱۴ - تاریخ: ۱۳۹۲/۰۶/۱۸
سلام خسته نباشيد بنده ماي اس كيو ال رو تو ويندوز سون نصب كردم وقتي تو cmsdos يوزر با پسورد رو وارد مي كنم برنامه قطع ميشه براي رفع اين اشكال بايد چكار كنم با تشكر
پاسخ: 
سلام
سوالان واضح نیست!
منظور از cmsdos مشخص نیست؟
توصیه می کنیم از برنامه هایی مانند WampServer استفاده کنید.
نویسنده: مومني موگويي
زمان: ۰۹:۴۳:۲۸ - تاریخ: ۱۳۹۲/۰۶/۲۰
باز هم سلام بنده منظورم اينكه وقتي ماي اس كيو ال رو نصب مي كنم بعد وقتي يوزر پسورد رو وارد mysql command line client مي كنم بعد از چند ثانيه برنامه ماي اس كيو ال يه بوق مي زنه و كلا قطع ميشه به نظر شما مشكل از نصب ماي اس كيو ال هست يا از چيز ديگه ممنون
پاسخ: 
سلام
نصب MySQL به صورت مستقیم در ویندوز کار تقریبا حساسی است، به همین خاطر چندان کاربردی نیست (تجربه زیادی در این خصوص نداریم) و بیشتر تمایل به استفاده از برنامه هایی مانند WampServer و... است که فرآیند نصب پایگاه داده را نیز به صورت خودکار انجام می دهند، با این حال می توانید از دستورالعمل لینک زیر پیروی کنید:
http://www.webdevelopersnotes.com/how-do-i/install-mysql-windows-7.php
ممکن است در قسمتی دچار اشتباه شده باشید.
نویسنده: مومني موگويي
زمان: ۱۸:۳۲:۵۸ - تاریخ: ۱۳۹۲/۰۶/۲۰
سلام دوست گرامي يه دنيا ممنون از لطفتون موفق باشيد
نویسنده: سعید
زمان: ۱۰:۳۹:۰۵ - تاریخ: ۱۳۹۲/۰۷/۲۲
سلام
خسته نباشید
اگر برای ساخت موتور جستجوی سایت از کد زیر استفاده کنیم ایرادی ندارد؟ چون من قبلاً با کلمه REGEXP برخورد نکرده بودم.
$check = mysql_query("SELECT id FROM tbl WHERE tit REGEXP '$item2|$item1|$item3'") or die(mysql_error());
اخه میدونید توی دستورات mysql یه دستور like داریم اما نمی دونم این دستور یهو از کجا پیداش شد. جالب اینجاست که خیلی هم دستور جمع و جوریه!
چون این دستور نتیجه میده صد در صد هم وجود داره اما می خواستم بدونم جزو توابع mysql حساب میشه یا ساختار اصلیه!
با تشکر و سپاس از شما
پاسخ: 
سلام
عملگر REGEXP جزء موارد استاندارد MySQL است:
http://dev.mysql.com/doc/refman/5.1/en/regexp.html
که با آن امکان استفاده از عبارات با قاعده در پرس و جوهای دیتابیس مهیا می شود، باید توجه داشته باشید که در کل LIKE روش سریع تر و بهینه تری نسبت به REGEXP است (هر چند REGEXP در مواردی کاربردهای خاص خود را دارد)، به همین دلیل استفاده از REGEXP در زمانی که می توانید از LIKE استفاده کنید، توصیه نمی شود.
نویسنده: sanobar
زمان: ۱۱:۲۶:۴۳ - تاریخ: ۱۳۹۲/۰۸/۱۶
سلام
اگه بخواهیم چند تا جمله یا کلمه رو در دیتابیس سرچ کنیم و هر ردیف که یکی از اون جمله های رو داشت به نتایج برگشتی اضافه کنه چطور باید با MATCH AGAINST نوشت ؟
مثلا این کلمات رو داریم :
hello , test
با like اینطوری میشه :
where `name` like "%hello%" or `name` like "%test%"
یه روش ساده تر هم هست
where `name` IN('test','hello')
حالا با MATCH AGAINST چطوری میشه نوشت ؟
پاسخ: 
سلام
از نمونه زیر استفاده کنید:
SELECT * FROM `tbl` WHERE MATCH(`col_1`) AGAINST('word_1') OR MATCH(`col_2`) AGAINST('word_2');
paged صفحه 1 از 4




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

6 × 8
 refresh
آگهی
seonab.com
طراحی نرم افزار اندروید
رنگین کمان عکس
Ranginkamaan.com

آرشیو عکس های باکیفیت با موضوعات متنوع...