Так как мой приветственный топик об открытии сайта idea2.ru заминусовали :) — пишу в своём блоге :)
Короче — сижу сегодня жду пока отмокнут джинсы, которые я наконец-то собрался постирать и вдруг решил добавить нативный поиск по сайту на базе LS :)
Что из этого получилось можно посмотреть на idea2.ru
А реализовано это функцией которая представляет собой небольшую модификацую функции поиска по тегам :)
Поиск осуществляется по теме и тексту топика банальным
LOWER(topic_text) LIKE LOWER('%{$sTag}%')
Итак для установки потребуется:
самым важным шагом является загрузка картинки для поиска :)
1. в templates\skin\habra\img\ загружаем search.gif
2. в templates\skin\habra\header.tpl
найти закомментированное место формы поиска и туда вставить
/**
* Получает список топиков по тексту (поиск)
*
* @param unknown_type $sTag
* @param unknown_type $iCount
* @param unknown_type $iPage
* @param unknown_type $iPerPage
* @return unknown
*/
public function GetTopicsBySearch($sTag,$iCount,$iPage,$iPerPage) {
if (false === ($data = $this->Cache_Get("topic_mysearch_{$sTag}_{$iPage}_{$iPerPage}"))) {
$data = array('collection'=>$this->oMapperTopic->GetTopicsBySearch($sTag,$iCount,$iPage,$iPerPage),'count'=>$iCount);
$this->Cache_Set($data, "topic_mysearch_{$sTag}_{$iPage}_{$iPerPage}", array('topic_update','topic_new'), 60*15);
}
return $data;
}
8. и соответственно редактируем classes\modules\topic\mapper\Topic.mapper.class.php
//
// поиск текста по топикам
//
public function GetTopicsBySearch($sTag,&$iCount,$iCurrPage,$iPerPage)
{
$iCurrentUserId=-1;
if (is_object($this->oUserCurrent)) {
$iCurrentUserId=$this->oUserCurrent->getId();
}
$sql = " SELECT
t.*,
tc.*,
u.user_login as user_login,
b.blog_title as blog_title,
b.blog_type as blog_type,
b.blog_url as blog_url,
IF(tv.topic_id IS NULL,0,1) as user_is_vote,
tv.vote_delta as user_vote_delta,
IF(tqv.topic_id IS NULL,0,1) as user_question_is_vote
FROM (
SELECT DISTINCT
topic_id
FROM
".DB_TABLE_TOPIC_CONTENT."
WHERE
LOWER(topic_text) LIKE LOWER('%{$sTag}%')
UNION
SELECT DISTINCT
topic_id
FROM ".DB_TABLE_TOPIC."
WHERE
LOWER(topic_title) LIKE LOWER('%{$sTag}%')
ORDER BY topic_id DESC
) as tt
JOIN ".DB_TABLE_TOPIC." AS t ON tt.topic_id=t.topic_id
JOIN ".DB_TABLE_USER." AS u ON t.user_id=u.user_id
JOIN ".DB_TABLE_BLOG." AS b ON t.blog_id=b.blog_id
LEFT JOIN (
SELECT
topic_id,
vote_delta
FROM ".DB_TABLE_TOPIC_VOTE."
WHERE user_voter_id = ?d
) AS tv ON tt.topic_id=tv.topic_id
LEFT JOIN (
SELECT
topic_id
FROM ".DB_TABLE_TOPIC_QUESTION_VOTE."
WHERE user_voter_id = ?d
) AS tqv ON tt.topic_id=tqv.topic_id
LEFT JOIN ".DB_TABLE_TOPIC_CONTENT." AS tc ON tt.topic_id=tc.topic_id
;
";
$aTopics=array();
$iCount=0;
if ($aRows=$this->oDb->select($sql,$sTag,($iCurrPage-1)*$iPerPage, $iPerPage,$iCurrentUserId,$iCurrentUserId)) {
foreach ($aRows as $aTopic) {
$aTopics[]=new TopicEntity_Topic($aTopic);
$iCount++;
}
//$iCount=$this->GetCountTopicsBySearch($sTag);
}
return $aTopics;
}
Всё :)
Вроде ничего не забыл :)
PS если вас заинтересовала судьба джинсов — они постираны и сейчас сохнут на балконе :)))
UPD
вот архив с файлами http://karta39.ru/blog/wp-content/uploads/2009/02/ls-search.zip
однако, я использовал дистрибутив не из svn-на, а скачивал с sf, так что лучше всё же просто добавить нужные функции в файлы вашего проекта.
из проблем с поиском — в настоящее время почему-то не формируются страницы найденного — всё найденное выводится на одной странице :( UPD 2 проблема c постраничным выводом результатов поиска решается так
так же при попытке перехода на следующую страницу выпадало предупреждение в отсутствии searchfor
убираем предупреждение так :))
if (preg_match("/searchfor/i",$sTag))
{
$sTag = $_GET['searchfor'];
}
Если я правильно понял то это реализация поиска без использования sphinx. Тем кто на обычном хостинге может очень пригодиться. Пока не проверял, а вообще респект, молодец. Я только не понял почему столько комментариев удаленных?
да — вы поняли правильно :) в комментариях был мусор — топик не опубликовался до конца — времени разбираться в чём проблема не было — я спешил убегать :) и я запостил продолжение в комментариях :)
не прошло и нескольких часов, как добавляется небольшое улучшение :)
заменить поиск в topic_text на topic_text_source, чтобы не было неправильного срабатывания на код Geshi ;)
вот архив с файлами http://karta39.ru/blog/wp-content/uploads/2009/02/ls-search.zip
однако, я использовал дистрибутив не из svn-на, а скачивал с sf, так что лучше всё же просто добавить нужные функции в файлы вашего проекта.
из проблем с поиском — в настоящее время почему-то не формируются страницы найденного — всё найденное выводится на одной странице :(
так же при попытке перехода на следующую страницу выпадало предупреждение в отсутствии searchfor
убираем предупреждение так :))
if (preg_match("/searchfor/i",$sTag))
{
$sTag = $_GET['searchfor'];
}
как только эту проблему решу — сразу дам знать :)
Офигеть круто!
А вы бы не могли нормаль статью написать, и все оформить?
Просто Сфинкс — я не могу поставить, у меня простой хостинг.
Поиск от ГУГЛА тоже не особо рулит, а может ваш лучше индексирует? Как вы думаете?
Можно пример посмотреть вашего поиска?
Он к ЛС 0,3 подходит?
Ответы есть, но их надо искать в самих комментариях. Это не очень удобно. Ссылки на архивы и какие-то изменения (как например эту) в последствие надо добавлять в топик, чтобы потом не читать все комментарии.
Проблема с постраничным выводом результатов поиска была в следующем:
В файле Topic.mapper.class.php в функции GetTopicsBySearch необходимо было посчитать вначале общее количество строк в таблице удовлетворяющих поисковому запросу, а уже во втором запросе вытаскивать данные относящиеся к конкретной странице результатов. Осталось только оптимизировать первый запрос, что бы он выдавал только количество строк. Я бы и рад это сделать, но в SQL я увы не силён — для меня это тёмный лес.
<code>//
// поиск текста по топикам
//
public function GetTopicsBySearch($sTag,&$iCount,$iCurrPage,$iPerPage)
{
$iCurrentUserId=-1;
if (is_object($this->oUserCurrent)) {
$iCurrentUserId=$this->oUserCurrent->getId();
}
$sql = " SELECT
t.*,
tc.*,
u.user_login as user_login,
b.blog_title as blog_title,
b.blog_type as blog_type,
b.blog_url as blog_url,
IF(tv.topic_id IS NULL,0,1) as user_is_vote,
tv.vote_delta as user_vote_delta,
IF(tqv.topic_id IS NULL,0,1) as user_question_is_vote
FROM (
SELECT DISTINCT
topic_id
FROM
".DB_TABLE_TOPIC_CONTENT."
WHERE
LOWER(topic_text_source) LIKE LOWER('%{$sTag}%')
UNION
SELECT DISTINCT
topic_id
FROM ".DB_TABLE_TOPIC."
WHERE
LOWER(topic_title) LIKE LOWER('%{$sTag}%')
ORDER BY topic_id DESC
) as tt
JOIN ".DB_TABLE_TOPIC." AS t ON tt.topic_id=t.topic_id
JOIN ".DB_TABLE_USER." AS u ON t.user_id=u.user_id
JOIN ".DB_TABLE_BLOG." AS b ON t.blog_id=b.blog_id
LEFT JOIN (
SELECT
topic_id,
vote_delta
FROM ".DB_TABLE_TOPIC_VOTE."
WHERE user_voter_id = ?d
) AS tv ON tt.topic_id=tv.topic_id
LEFT JOIN (
SELECT
topic_id
FROM ".DB_TABLE_TOPIC_QUESTION_VOTE."
WHERE user_voter_id = ?d
) AS tqv ON tt.topic_id=tqv.topic_id
LEFT JOIN ".DB_TABLE_TOPIC_CONTENT." AS tc ON tt.topic_id=tc.topic_id
;
";
$iCount=0;
if ($aRows=$this->oDb->select($sql,$sTag,($iCurrPage-1)*$iPerPage, $iPerPage,$iCurrentUserId,$iCurrentUserId)) {
foreach ($aRows as &$value) {
$iCount++;
}
}
$Start=($iCurrPage*$iPerPage)-$iPerPage;
$sql = " SELECT
t.*,
tc.*,
u.user_login as user_login,
b.blog_title as blog_title,
b.blog_type as blog_type,
b.blog_url as blog_url,
IF(tv.topic_id IS NULL,0,1) as user_is_vote,
tv.vote_delta as user_vote_delta,
IF(tqv.topic_id IS NULL,0,1) as user_question_is_vote
FROM (
SELECT DISTINCT
topic_id
FROM
".DB_TABLE_TOPIC_CONTENT."
WHERE
LOWER(topic_text_source) LIKE LOWER('%{$sTag}%')
UNION
SELECT DISTINCT
topic_id
FROM ".DB_TABLE_TOPIC."
WHERE
LOWER(topic_title) LIKE LOWER('%{$sTag}%')
ORDER BY topic_id DESC
LIMIT ".$Start.", ".$iPerPage."
) as tt
JOIN ".DB_TABLE_TOPIC." AS t ON tt.topic_id=t.topic_id
JOIN ".DB_TABLE_USER." AS u ON t.user_id=u.user_id
JOIN ".DB_TABLE_BLOG." AS b ON t.blog_id=b.blog_id
LEFT JOIN (
SELECT
topic_id,
vote_delta
FROM ".DB_TABLE_TOPIC_VOTE."
WHERE user_voter_id = ?d
) AS tv ON tt.topic_id=tv.topic_id
LEFT JOIN (
SELECT
topic_id
FROM ".DB_TABLE_TOPIC_QUESTION_VOTE."
WHERE user_voter_id = ?d
) AS tqv ON tt.topic_id=tqv.topic_id
LEFT JOIN ".DB_TABLE_TOPIC_CONTENT." AS tc ON tt.topic_id=tc.topic_id
;
";
$aTopics=array();
if ($aRows=$this->oDb->select($sql,$sTag,($iCurrPage-1)*$iPerPage, $iPerPage,$iCurrentUserId,$iCurrentUserId)) {
foreach ($aRows as $aTopic) {
$aTopics[]=new TopicEntity_Topic($aTopic);
}
}
return $aTopics;
}</code>
наверное имеется в виду новая версия LS — 0.3
например, можно использовать костыль: создать свой js-файл и туда поместить эту функцию, а потом прописать файл в хидере нужных шаблонов.
не знаю (не смог пока что разобраться) с чем это связано, но по тегам-меткам поиск не совсем корректно происходит.
Проверял по определенному запрос, который находился только в метках публикации. И в результате по поиску я на данную публикацию (которую брал как пример) я не вышел. В чем может быть проблема, кто-нибудь сталкивался?
так я вроде бы поставил его на SVN(кажется 263)
все работает, как бы…
но вот интересно вбиваю в поиск, выгоняет список тем по искомому, нажимаю на название топика, и в момент до загрузки страницы с топиком, на доли секунды всплывает окно с «добавлением изображения»… странно. что я не так сделал, придется искать…
И еще вопрос, почему вот здесь:
, (выделение поиска),
Вопрос по поиску.
Как можно найти человека, если помнишь только город. В тегах на LS значатся не все города. К примеру нет Твери и Рыбинска, а зарегистрированные пользователи есть. Ввожу в поиске «Тверь» или «Рыбинск» и получаю: «Удивительно, но поиск не дал результатов».
Привет из Твери) Ты немного путаешь. Этот поиск не сканирует поля профилей, идет поиск только по топикам и комментариям.
Не все города в тегах peoples, потому, что выводится какое то определенное количество городов с максимальным числом указавших этот город, если например ты забьешь, что ты из Твери, то в /peoples/ наш город появится.
Ну коль пошла такая пьянка, то передать значение из текстового поля(кстати, с юзаньем Autocompliter) элементарно.
Или же сделать полное облако городов. Кстати второе — очень даже хорошая идея… на отдельной странице /peoples/cities/ отдельным экшеном.
Странно. Разархивировал все. Раскидал папки, внес строку в header.tpl. Но когда выдает результаты поиска, в поисковой строке всегда topics и, как следствие, «Сюда еще никто не успел написать»
84 комментария
заменить поиск в topic_text на topic_text_source, чтобы не было неправильного срабатывания на код Geshi ;)
вот архив с файлами
однако, я использовал дистрибутив не из svn-на, а скачивал с sf, так что лучше всё же просто добавить нужные функции в файлы вашего проекта.
из проблем с поиском — в настоящее время почему-то не формируются страницы найденного — всё найденное выводится на одной странице :(
так же при попытке перехода на следующую страницу выпадало предупреждение в отсутствии searchfor
убираем предупреждение так :))
if (preg_match("/searchfor/i",$sTag))
{
$sTag = $_GET['searchfor'];
}
как только эту проблему решу — сразу дам знать :)
А вы бы не могли нормаль статью написать, и все оформить?
Просто Сфинкс — я не могу поставить, у меня простой хостинг.
Поиск от ГУГЛА тоже не особо рулит, а может ваш лучше индексирует? Как вы думаете?
Можно пример посмотреть вашего поиска?
Он к ЛС 0,3 подходит?
относительно LS 0.3 пока сказать не могу — ещё не обновился :)
Проблема с постраничным выводом результатов поиска была в следующем:
В файле Topic.mapper.class.php в функции GetTopicsBySearch необходимо было посчитать вначале общее количество строк в таблице удовлетворяющих поисковому запросу, а уже во втором запросе вытаскивать данные относящиеся к конкретной странице результатов. Осталось только оптимизировать первый запрос, что бы он выдавал только количество строк. Я бы и рад это сделать, но в SQL я увы не силён — для меня это тёмный лес.
С уважением ALF.
я так и думал :) вот только думал всё же обойтись одним запросом :)
однако даже с двумя запросами никак не получается заставить работать :(
например, можно использовать костыль: создать свой js-файл и туда поместить эту функцию, а потом прописать файл в хидере нужных шаблонов.
вас не затруднит поподробнее расписать, как это сделать.
код в header_nav.tpl оставит дизайн поля поиска и кнопки
Проверял по определенному запрос, который находился только в метках публикации. И в результате по поиску я на данную публикацию (которую брал как пример) я не вышел. В чем может быть проблема, кто-нибудь сталкивался?
все работает, как бы…
но вот интересно вбиваю в поиск, выгоняет список тем по искомому, нажимаю на название топика, и в момент до загрузки страницы с топиком, на доли секунды всплывает окно с «добавлением изображения»… странно. что я не так сделал, придется искать…
И еще вопрос, почему вот здесь:
, (выделение поиска),
нельзя применить теги меняющие цвет и размер текста? только(<.b><./b>)?
в файле /templates/skin/new/actions/ActionBlog/comment.tpl строку
становится все нормально.
В какой файл можно перенести этот код:
чтобы осталась работать функция вставки картинок в комментариях..?
\classes\actions\ActionSearch.class.php
Берём функцию из этого сообщения:
и вставляем её в Topic.mapper.class.php
Создаём папку:
\templates\skin\new\actions\ActionSearch
В этой папке создаём файлик index.tpl к следующего содержания:
Никакого java скрипта специально добавлять не нужно.
Вроде ничего не забыл, если что поправьте меня.
Извиняюсь за портянку.
(Использую денвер)
так как можно это исправить?
Как можно найти человека, если помнишь только город. В тегах на LS значатся не все города. К примеру нет Твери и Рыбинска, а зарегистрированные пользователи есть. Ввожу в поиске «Тверь» или «Рыбинск» и получаю: «Удивительно, но поиск не дал результатов».
Не все города в тегах peoples, потому, что выводится какое то определенное количество городов с максимальным числом указавших этот город, если например ты забьешь, что ты из Твери, то в /peoples/ наш город появится.
Хотя поиск по городам я думаю некритичен :)
Или же сделать полное облако городов. Кстати второе — очень даже хорошая идея… на отдельной странице /peoples/cities/ отдельным экшеном.
Мне кажется это лучше чем — прикручивать поиск(+Рекламу) google
имхо
— заменить стандартную форму поиска на:
Вообще, спасибо большое. Действительно здорово. Если нет возможности сфинкса поставить — это именно то, что нужно.