Търсене в две полета - логически израз?
Автор |
|
insecteaterВто, 05.12.06, 10:27 |
Има ли програмисти из тоя сайт? Функциите са на php, но това няма значение за логиката. ------------------Въведение-------------------------- Всички знаете как се търси с търсачка. търсеното трябва да съдържа всички думи зададени в полето за търсене, но НЕ трябва да съдържа думи, пред които има знака минус. Та аз имам такава функция. search($what, $container), която връща true ако намери нещо и false ако не намери. Дотук всичко добре. Ето даже един пример: Връща true за всичко, което съдържа думата "Христо" и НЕ съдържа думата "Ботев" -------------------Проблем---------------------------- Ситуацията обаче се обърква ако са замесени две или повече полета. Например израза search('Христо', $column1) || search('Христо', $column2) |
ще върне true ако поне в едното поле се среща думата "Христо" както и се очаква ОБАЧЕ израза search('Христо - Ботев', $column1) || search('Христо -Ботев', $column2) |
ще върне true, даже ако в кое да е поле се среща думата "Ботев" (въпреки знака минус) Идеята е ако поне в едното поле (а не и в двете, както е сега) се съдържа думата Ботев, да се върне false. Един логически израз да става за всички случаи. MySQL в случая не се използва изобщо. Засега съм намерил решение като просто обединя двете полете (конкатенация). Има ли логически израз който да замести конкатенацията И изобщо не е ли по рационално полетата да се съединяват и така да се претърсват, вместо да се търси логически израз. | | milenВто, 05.12.06, 11:09 | RE: Търсене в две полета - логически израз?
Аз съм един от създателите на Download.BG, който е направен на PHP и MySQL. Разгледай търсачката, например в раздел програми. Имай предвид, че знака "-" при нас е заменен от "^". Това е така, защото повечето потребители не използват правилно знака "-" (дори и в Google, независимо от многото образователни статии по отношение синтаксиса на търсене). Много пишат Flash-get или "най-добрата програма за ". Кавичките за фраза също работят, но и без тях резултатите са подредени. Може би мога да предложа решение на проблема, ако ми покажеш предметната област в която търсиш. Например при нас, правим предварителна конкатенация на полетата на всеки обект, за да можем да използваме едни и същи функции за пълнотекстово търсене. Паметта в базата данни не е толкова голям проблем, колкото правилността на търсенето и скоростта. | | insecteaterВто, 05.12.06, 12:31 |
Благодаря за отзива. И аз мисля че съединяването е най добре, когато е въвлечен - (респ. ^). Така го оставих и без това. Относно това::
Цитат ” Много пишат Flash-get или "най-добрата програма за ". „ Аз процедирам по следният начин: 1. Извличам фразите заградени с кавички в масив чрез регулярен израз (заедно със знака минус ако има пред тях), и ги премахвам от низа за търсене 2. След това низа за търсене го пренасям в масив, като използвам за разделител знака за интервал 3. Съединявам двата масива (голите думи и фразите) отделям в отделен масив думите (фразите) ПРЕД които има знак минус, а в старият остават тези БЕЗ минус В НАЧАЛОТО 4. В зависимост от случая, съставям заявка за MySQL от елементите на масивите, или обхождам и прилагам stristr за всеки елемент (Ако няма MySQL). по този начин flash-get ще търси за низа"'flash-get" и изобщо тиренцето което е вътре във фраза или словосъчетание, няма да бъде вземано в предвид. Остава отрит въпроса как ще се интерпретира търсене от сорта на flash-"get е най добрата" Без интервал преди тирето. И как би трябвало да се интерпретира P.S. Като стана готов, ще оставя адрес да покажа какво се е получило. Макар че имам нещо подобно на http://www.bghouses.com. Абсолютно целият сайт е моя изработка (+MySQL), но не помня вече как точно правих търсенето (Правен е отдавна и вече не съм отговорен за него, сорса е архивиран някъде из шкафа). Там обаче няма свободен низ за търсене и общо взето заявките се правят от долепване на критериите. | | milenПон, 11.12.06, 10:27 | Търсене в две полета - интерпретиране на заявката на потребителя
В Download.BG за статистиката пазим последните 2 милиона заявки за търсене. Разглеждал съм извадки от тях и мога да твърдя че потребителите въобще не се интересуват от синтаксиса за точно търсене. Това разбира се е така, защото потребителите на Download.BG в общия случай не са ИТ професионалисти. Съвсем малка част пробват неща като: - минус за изваждане от списъка с резултатите - AND OR за логически изрази - кавички за търсене на цели фрази Програмистите живеят в обкръжение на програмисти и разбирането им за потребителите е изкривено. Потребителите искат да напишат една две думи и да получат желания резултат. Затова в Download.BG ние направихме нещо друго: вдигаме рейтинга на резултати, където търсените думи се намират в същата последователност както са зададени от потребителя. Последователностите от думи се прекъсват от кавичките. Освен това проверяваме за слято изписване на думите: Например: flash get ще търси най вече резултати където има flashget, "flash get, flash и get в тази последователност. Сега като гледам, на 10 заявки 7 успяват да намерят това, което търсят. разбира се има проблем със следните 2 групи потребители: - крайно неграмотните, които пишат например на български с латиница, например "programa za gledane na filmi" те са около 25% от потребителите; - "хакерите", които използват несъществуващ синтаксис като and, or и т.н. Хайде, като направиш търсенето, ще го пробваме ;) | | anonymousПон, 11.12.06, 15:35 |
Ако правилно съм разбрал въпроса: <html>
<head><title>Search</title></head>
<body>
<?php
// Full-Text Search Example
// Conect to the database.
$cnx = mysql_connect('localhost', 'phpfreaks', 'phpfreaks') or die ("Could not connect");
mysql_select_db('phpfreaks_search', $cnx) or die (mysql_error());
// Create the search function:
function searchForm()
{
// Re-usable form
// variable setup for the form.
$searchwords = (isset($_GET['words']) ? htmlspecialchars(stripslashes($_REQUEST['words'])) : '');
$normal = (($_GET['mode'] == 'normal') ? ' selected="selected"' : '' );
$boolean = (($_GET['mode'] == 'boolean') ? ' selected="selected"' : '' );
echo '<form method="get" action="'.$_SERVER['PHP_SELF'].'">';
echo '<input type="hidden" name="cmd" value="search" />';
echo 'Search for: <input type="text" name="words" value="'.$searchwords.'" /> ';
echo 'Mode: ';
echo '<select name="mode">';
echo '<option value="normal"'.$normal.'>Normal</option>';
echo '<option value="boolean"'.$boolean.'>Boolean</option>';
echo '</select> ';
echo '<input type="submit" value="Search" />';
echo '</form>';
}
// Create the navigation switch
$cmd = (isset($_GET['cmd']) ? $_GET['cmd'] : '');
switch($cmd)
{
default:
echo '<h1>Search Database!</h1>';
searchForm();
break;
case "search":
searchForm();
echo '<h3>Search Results:</h3><br />';
$searchstring = mysql_escape_string($_GET['words']);
switch($_GET['mode'])
{
case "normal":
$sql = "SELECT mytable_id, mytable_title, mytable_caption, mytable_dts,
MATCH(mytable_title, mytable_caption, mytable_full_body)
AGAINST ('$searchstring') AS score FROM mytable
WHERE MATCH(mytable_title, mytable_caption, mytable_full_body)
AGAINST ('$searchstring') ORDER BY score DESC";
break;
case "boolean":
$sql = "SELECT mytable_id, mytable_title, mytable_caption, mytable_dts,
MATCH(mytable_title, mytable_caption, mytable_full_body)
AGAINST ('$searchstring' IN BOOLEAN MODE) AS score FROM mytable
WHERE MATCH(mytable_title, mytable_caption, mytable_full_body)
AGAINST ('$searchstring' IN BOOLEAN MODE) ORDER BY score DESC";
break;
}
// echo $sql;
$result = mysql_query($sql) or die (mysql_error());
while($row = mysql_fetch_object($result))
{
echo '<strong>Title: '.stripslashes(htmlspecialchars($row->mytable_title)).'</strong><br />';
echo 'Score:'. number_format($row->score, 1).' Date: '.date('m/d/y', $row->mytable_dts).'<br />';
echo '<p>'.stripslashes(htmlspecialchars($row->mytable_caption)).'</p>';
echo '<hr size="1" />';
}
break;
}
?>
</body>
</html> |
| | insecteaterВто, 12.12.06, 11:59 |
yogi--, мерси и на теб. Чувствам се малко гузно. Имам един не толкова голям текстов файл с местоположения и координати на места от карти на една ИГРА. Т.е. на мен това не ми трябваше за нищо сериозно. MySQL изобщо не е замесен при мен. Но пък се получи хубаво преподаване на опит, за което благодаря. Иначе адреса е http://InsectEater.no-ip.info/mm7/locations.php (Сочи към моят компютър, а съм на БТК, така че има шанс да не се вижда от време на време, докато се update-не DNS-а). А там използвам както съм описал по-горе разделяне на думите и след това претърсване със stristr. Просто като гъбена чорба. Тежката артилерия на MySQL и е рано още . Иначе MATCH() ... AGAINST() наистина е доста гъвкаво, но на мен все още не ми се е налагало да ги използвам както трябва. Проектите ми все включват филтриране , отколкото търсене. Колкото до това: - крайно неграмотните, които пишат например на български с латиница, например "programa za gledane na filmi" те са около 25% от потребителите; Ами ... не знам какво да кажа :( Ако наистина са 25% Сериозно почвам да се опасявам за бъдещето ни като "културна" нация. P.S. Какъв е начина за търсене из форума и статиите на download.bg с включени ВСИЧКИ думи от заявката? | | anonymousВто, 12.12.06, 13:08 |
Гоогле от тарсачката си направиха милярди. микрософт /колегите ви/ са мъчат да го конкурират а ти искаш да го направиш -сас фрее ........... то се казва МАТЕМАТИКАТА на тарсачката,АЛГОРИТАМА и парво си изясни даже при гоогле се случва като тарсиш нещо-да ти предложат .............19 милиона страници. Ама на клиента му трябва само една-тази дето я иска тои. проблема е чиста математика...... | | anonymousВто, 12.12.06, 18:09 |
Не знам дали ще мога да обесня идеята като хората. Работата е там, че не разполагам с много време в момента. Та: Идеята е следната. Да кажем, че записваш търсения стринг в $what_search. Разделяме думите в него с $search_tmp = explode(" ", $what_search); За разделител използваме интервал-а и ги набиваме в масива $search_tmp. След което си правим един цикъл, разбира се, ако има нещо в този масив, и проверяваме всяка дума за някакъв знак. Минус, плус, кото там. И слагаме в нов масив $searching_for само тези думи, които трябва да пресъстват. if ($search_tmp) { // Ако не е празен
for ($i=0; $i <= sizeof($search_tmp); $i++) { // за всеки елемент от масива
if (substr($search_tmp[$i], 0, 1) == '-') // в случая гледаме дали има -
continue; // ако има редовете до края на цикъла не се изпълняват, а той си продължава
$searching_for .= $search_tmp; // ако няма - вкарваме думата
} // end of FOR
} // end of IF
|
Така имаш масив $searching_for, който съдържа думите за търсене. Може, разбира се, да се направи и по още различни начини. Просто, тея дни времето ми е малко недостатъчно ;( Успех. | | insecteaterВто, 12.12.06, 18:28 |
function find($search, $container) {
$search = stripslashes($search);
$search = str_replace(""", '"', $search);
$quotes = array();
//Extract phrases in quotes
preg_match_all('/(-?)"(.*?)"/', $search, $phrases, PREG_SET_ORDER);
//Delete extracted quotes
$search = preg_replace('/-?"(.*?)"/', "", $search);
//Phrases processing
for ($i=0; $i < count($phrases); $i++) {
$ph = $phrases[$i][2];
//Find the "-" sign
if (chr(ord($phrases[$i][1])) == "-") {
$ph = preg_replace("/^-/", "", $ph);
$ph = '-'.$ph;
}
$quotes[] = $ph;
}
$search = explode (' ', $search);
$search = array_merge($search, $quotes);
$search = array_filter($search);
foreach ($search as $word) {
if ($word[0] == '-') {
$word = substr($word, 1);
if (stristr($container, $word)) return false;
}
elseif (!stristr($container, $word)) return false;
}
return true;
} |
Ей тая функцийка съм си я сглобил отпреди месец - месец и половина някъде и си я ползвам за търсене на текст. Ако има предложения специално за кода по-горе, ще се радвам да ги видя. Редакция: Редактирах заради специалните знаици - по специално " ; | | Коментар |