Поменять математику поиска. Вместо поиска словосочетания сделать поиск отдельных слов
Есть сайт (trademosh.com). В нем есть поиск. Если в поле Scool name ... задать словосочетание, то поиски по словосочетанию и будет. По одному слову результаты не выводит. А надо.
Кнопка поиска.
$searchFind_Buut = <<< TEXT
<div id="searchFind_Buut" class="conteiner" >
<button id="findLatLon" class="submitButt" onClick="startFind($(this).closest('form'),{$is_mobile});" >Find</button><img id="ajaxLoader" class="ajaxLoader" src="{$LINK_baseUrl}images/ajax-loader_export.gif" alt="data is loading" style="vertical-align:bottom" />
<button id="resetAll" onclick="reset_();" class="submitButt" >Reset</button>
TEXT;
Механизм поиска Код:
// запрос на поиск по сайту ---------------------------------------------------------------- |
var allSearch = $.trim(allSearchFild.val()); Я так думаю здесь формируется слово для запроса? как преобразовать в отдельные слова фразу с элементом ИЛИ? |
думаю нужно sql-запрос править или как оно там у вас ищет
|
//global $Search;
$ID="";
$data = array();
$data["conteinerData"]="";
$d = (int)$_POST['d'];
$category = mysql_real_escape_string($_POST['cat']);
$gender = isset($_POST['gender'])?mysql_real_escape_string($_POST['gender']):null;
$category = $category=="Category"?"":$category;
$gender = $gender=="noGender"?"":$gender;
$minPrice = (float)$_POST['minPrice'];
$maxPrice = (float)$_POST['maxPrice'];
$selectSearchDD_emails_edu = !empty($_POST['selectSearchDD_emails_edu'])?_f::getAntiXSS($_POST['selectSearchDD_emails_edu']):""; // поиск по мыльному домену @..edu
$selectSearchDD_emails = !empty($_POST['selectSearchDD_emails'])?_f::getAntiXSS($_POST['selectSearchDD_emails']):""; // поиск по мыльному домену
$Search = !empty($_POST['Search'])?_f::getAntiXSS($_POST['Search']):"";
$lat = (FLOAT)$_POST['lat'];
$lon = (FLOAT)$_POST['lon'];
$corStr=(int)$_POST['cor_str'];
$limit_from = $corStr*$limit-$limit;
$search = ""; // общий поиск по сайту
$location = "1=1"; // локация и удаление
$TG="";
if ($category!="")
{
$genderW = !empty($gender)? " gender='"._f::getAntiXSS($gender)."' ": " gender != 'null' ";
$type = " type='"._f::getAntiXSS($category)."' ";
$TG = "( {$type} AND {$genderW} )";
}
if (!empty($selectSearchDD_emails_edu))
{
$email = " email LIKE ('%{$selectSearchDD_emails_edu}%') ";
}
else
{
if(!empty($selectSearchDD_emails))
{
if ($selectSearchDD_emails=="other")
{
$email = " ( email NOT LIKE ('%.com%') AND email NOT LIKE ('%.edu%') ) ";
}else $email = " email LIKE ('%{$selectSearchDD_emails}%') ";
}
}
if (!empty($Search))
{
$arrWHEREs = array
(
" name LIKE ('%{$Search}%')",
" address LIKE ('%{$Search}%')",
" description LIKE ('%{$Search}%')",
" link LIKE ('%{$Search}%')",
" vlink LIKE ('%{$Search}%')",
" email LIKE ('%{$Search}%')",
" type LIKE ('%{$Search}%')",
" age LIKE ('%{$Search}%')",
" gender LIKE ('%{$Search}%')",
" price LIKE ('%{$Search}%')",
" date LIKE ('%{$Search}%')",
);
$search = " ( ".implode(" or ", $arrWHEREs)." ) ";
} else $search ="";
$arrWHERE = array();
if (!empty($TG)) $arrWHERE[]=$TG;
if (!empty($email)) $arrWHERE[]=$email;
$search2 = implode(" and ", $arrWHERE);
$AND = empty($search2) || empty($search) ?" ":" AND ";
$search = trim($search.$AND.$search2);
if (empty($search)) $search="1=1";
if (!empty($lat))
{
$location = "( ( ACOS( SIN( {$lat} * PI() / 180) * SIN(lat * PI() / 180) + COS( {$lat} * PI() / 180) * COS(lat * PI() / 180) * COS(({$lon} - lng) * PI() / 180) ) * 180 / PI()) * 60 * 1.1515)<=$d";
}
$qr = "SELECT * FROM markers WHERE ( ( {$location} ) AND ( {$search} ) AND price BETWEEN {$minPrice} AND {$maxPrice} ) AND varifMail='Ok' ORDER BY `date` DESC ";
$data["qr"]= IS_DEBUG===TRUE?$qr:"is debug off";
$_SESSION['query']=$qr;
$result = $bd->query($qr." LIMIT $limit_from, $limit ");
$data["kolVo"]=0;
// Creates an array of strings to hold the lines of the KML file.
setKML();
$kol_td = 1;
$resForData = $result;
if (!empty($isMobile))
{
//echo "Search result file kml";
$d = _t::contentAddsMobile($resForData);
}else
{
//echo "Search result file kml";
$d = _t::contentAddsDesctop($resForData);
}
$data['content']=array();
$data['content']=$d['content'][0];
for ($j=0; $j<count($d['row']); $j++){
$row = $d['row'][$j];
$data["kolVo"]++;
addKML($row["id"],$row["name"],$row["address"],$row["description"],$row["link"],$row["vlink"],$row["email"],$row["pic"],$row["type"],$row['gender'],$row["lng"],$row["lat"]);
$data["markers"]["lng"][]=$row["lng"];
$data["markers"]["lat"][]=$row["lat"];
}
Это наверное в этой части кода формируется поиск?
if (!empty($TG)) $arrWHERE[]=$TG;
if (!empty($email)) $arrWHERE[]=$email;
$search2 = implode(" and ", $arrWHERE);
$AND = empty($search2) || empty($search) ?" ":" AND ";
$search = trim($search.$AND.$search2);
if (empty($search)) $search="1=1";
Я просто пока еще не силен в программировании. Потому возможно мои вопросы довольно глупы. По моему решил, and и AND на or и OR поменял. Огромное спасибо форуму. Эффект генерала в полной мере доказан еще раз. |
Цитата:
Вы себя переоцениваете явно , не тратьте своё время и обратитесь сразу в раздел http://javascript.ru/forum/job/ либо на биржи фриланса |
Цитата:
|
И все таки прошу помощи. Как переделать запрос
if (!empty($TG)) $arrWHERE[]=$TG;
if (!empty($email)) $arrWHERE[]=$email;
$search2 = implode(" and ", $arrWHERE);
$AND = empty($search2) || empty($search) ?" ":" AND ";
$search = trim($search.$AND.$search2);
if (empty($search)) $search="1=1";
Чтобы в поиске не словоcочетания иcкались, а отдельные cлова? Что-то не помогло замена AND на OR |
Я бы вам рекомендовал почитать и разобраться с регулярными выражениями и функциями поиска по шаблону в PHP,
такими как: preg_match() и preg_replace() и, возможно, с функцией preg_split() |
Мне же надо в БД искать. Может можно просто запрос к БД соответствующий делать без вызова каждой записи и поиска совпадения. Я думаю можно, просто не знаю какой он должен быть.
|
Т.е вы хотите при вводе словосочетания искать не полное совпадение, а по отдельности каждое слово? Или у вас при вводе одного слова не ищет?
Ну во первых это форум по js )) Во вторых. Нужный кусок кода вот:
$arrWHEREs = array
(
" name LIKE ('%{$Search}%')",
" address LIKE ('%{$Search}%')",
" description LIKE ('%{$Search}%')",
" link LIKE ('%{$Search}%')",
" vlink LIKE ('%{$Search}%')",
" email LIKE ('%{$Search}%')",
" type LIKE ('%{$Search}%')",
" age LIKE ('%{$Search}%')",
" gender LIKE ('%{$Search}%')",
" price LIKE ('%{$Search}%')",
" date LIKE ('%{$Search}%')",
);
его и нужно править, если я правильно понял , что вы хотите. Или разбивать $Search на слова и создавать еще кучу LIKE либо объединять поля через concat и создавать столько LIKE сколько слов в запросе, но тут уже нужно изучать структуру бд, может быть не выгодно так делать. Либо юзать полнотекстовой поиск MATCH() AGAINST(),FULLTEXT ну или как альтернатива Sphinx. И третье, учится на том коде который вы привели не стоит. |
Хочу по отдельности каждое слово. Но ведь в той части кода что привел я (те 6 строк внизу) формируется запрос и добавляется AND(OR) между словами.
А в том что вы привели, уже идет сам поиск. Или я не прав? |
В том что я привел идет вставка из поля поиска, и туда вставляется все, что в строке поиска не разделяя никакими or, and и как я написал выше разделять нужно переменную $Search
допустим $Search='вася пупкин'; и $Search or $Search будет вася пупкин or вася пупкин - хоть как ты меняй or на and всеравно будет целоиковое 'вася пупкин' а не вася or пупкин or вася or пупкин и вставить в середину можно только разбивая переменную $Search и переписывая этот кусок кода. Да и выше я написал что можно и не разделять, если использовать полнотекстовой поиск, но нужно будет все равно тот кусок менять, а еще и индексы бд. В общем в любом случае вам работать именно с тем куском кода который я привел. А то, что вы привели - там совершенно в другом месте выставляется оператор, и к вашей задаче никак не относится. |
Вроде нашел обработку каждого слова. Еще один маленький вопрос. Как организовать цикл для массива
if (!empty($Search))
{
$arrWHEREs = array
(
" name LIKE ('%{$Search}%')",
" address LIKE ('%{$Search}%')",
" description LIKE ('%{$Search}%')",
" link LIKE ('%{$Search}%')",
" vlink LIKE ('%{$Search}%')",
" email LIKE ('%{$Search}%')",
" type LIKE ('%{$Search}%')",
" age LIKE ('%{$Search}%')",
" gender LIKE ('%{$Search}%')",
" price LIKE ('%{$Search}%')",
" date LIKE ('%{$Search}%')",
);
$search = " ( ".implode(" or ", $arrWHEREs)." ) ";
} else $search ="";
В который встроить такую обработку
if($search) {
//получаем массов чистых слов
$words = clearWords($search);
//добавляем ограничители для формирования условия WHERE к каждому слову
foreach($words as $k=>&$v) $v="'".$v."%'";
//формируем условие WHERE
$where = implode(" OR header like ".clearWords($search);
//отрезаем первое " OR" из условия
$where = preg_replace("/^\sOR/","",$where);
//формируем окончательный запрос к БД
//$query = "SELECT * FROM table WHERE ".$where;
}
Ну или как лучше всего совместить эти два условия? |
Почему не работает поиск если сделать так
if (!empty($Search))
{
$words = clearWords($Search);
foreach($words as $k=>&$v) $v="'".$v."%'";
{$arrWHEREs = array
(
" name LIKE ('%{clearWords($search)}%')",
" address LIKE ('%{clearWords($search)}%')",
" description LIKE ('%{clearWords($search)}%')",
" link LIKE ('%{clearWords($search)}%')",
" vlink LIKE ('%{clearWords($search)}%')",
" email LIKE ('%{clearWords($search)}%')",
" type LIKE ('%{clearWords($search)}%')",
" age LIKE ('%{clearWords($search)}%')",
" gender LIKE ('%{clearWords($search)}%')",
" price LIKE ('%{clearWords($search)}%')",
" date LIKE ('%{clearWords($search)}%')",
);}
$search = " ( ".implode(" or ", $arrWHEREs)." ) ";
} else $search ="";
|
Может просто для description новую переменную организовать и все. В принципе поиск по словам только для этого поля необходим.
|
я бы делал через полнотекстовой поиск, т.к. можно отсортировать по релевантности
if(!empty($Search)){
$arrWHEREs=array();
$Searchs=preg_split('/\s+/',$Search,-1,PREG_SPLIT_NO_EMPTY);
for($i=0,$s=sizeof($Searchs);$i<$s;$i++){
// if(mb_strlen($Searchs[$i])<2)continue; // раскомментировать если не нужны слова менее 2х символов пример: 'маша и петя' - 'и' не войдет в выборку
$arrWHEREs=array_merge($arrWHEREs,array
(
" name LIKE ('%{$Searchs[$i]}%')",
" address LIKE ('%{$Searchs[$i]}%')",
" description LIKE ('%{$Searchs[$i]}%')",
" link LIKE ('%{$Searchs[$i]}%')",
" vlink LIKE ('%{$Searchs[$i]}%')",
" email LIKE ('%{$Searchs[$i]}%')",
" type LIKE ('%{$Searchs[$i]}%')",
" age LIKE ('%{$Searchs[$i]}%')",
" gender LIKE ('%{$Searchs[$i]}%')",
" price LIKE ('%{$Searchs[$i]}%')",
" date LIKE ('%{$Searchs[$i]}%')",
));
}
$search=" ( ".implode(" or ", $arrWHEREs)." ) ";
}else $search="";
что там у вас в защите от xss и обеспечивает ли та защита защиту от sqlinj я хз. |
Цитата:
Cупер, работает как надо! :dance: Вроде бы. Огромное спасибо. Но если раскомментировать 5 строку, то поиск перестает работать. |
mbstring небось не включена
mb_strlen на strlen или включать mbstring |
| Часовой пояс GMT +3, время: 01:35. |