За последние 24 часа нас посетили 17730 программистов и 1621 робот. Сейчас ищут 1840 программистов ...

Поиск по всей базе

Тема в разделе "MySQL", создана пользователем Kreker, 14 мар 2008.

  1. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Знаю, что тем было много, но прошелся в поиске почти по всем - нужного не нашел.
    Мне нужен обычный поиск в 5 таблицах в пределах одной базы. Записей в сумме не особо много, тысяча - максимум, скорее всего.

    Касаемо самого запроса у меня такие идеи:
    1) Если слово одно - то ищем через LIKE
    2) Если слов больше - искать через полнотекстовый поиск в логическом режиме

    Дальше я у меня сомнения. Как правильно осуществить поиск вообще по тексту, если в нем возможно html-теги + как правильно сделать его на всю базу.
    Со вторым способом у меня такая идея была - просто делать 5 запросов в базу, а потом уже по общей релевантности выдавать результат, но я отказался от него. Да и как быть с html-тегами, не знаю.
    По поводу первого способа - вообще без понятия, как грамотно осуществить релевантность (правда об этом еще даже и не задумывался, поэтому возможно, что тороплюсь с вопросами).

    В инете на форуме нашел такую вещь:

    Эта вещица интересная. Мне кажется, что для меня вариант вполне подходящий, потому что:
    1) У меня не много записей => база распухнет, но не сильно. Хотя я читал, что от FULLTEXT она тоже распухает. Поэтому увеличение базы в размере может быть одинаковым (?)
    2) Все можно сделать одним запросом
    3) Быстродействие поиска (?)
    4) Более правильные результаты.

    Скажите правильный ли подход я планирую (с использованием подсказки с форума)? И как выявить релевантность при использовании LIKE?
    И самый главный вопрос - как вы устраиваете поиск? :)
     
  2. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    Kreker
    Мне fulltext не понравился что-то. Не время выполнения, а именно его отоброжение результатов... Использую LIKE.
     
  3. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Elkaz
    А структуру поиска как грамотнее реализовать? Как человек с форума написал? По-моему, лучший вариант, учитывая, что поиск будет осуществляться только по статьям, добавляемыми админом.

    Ну а если другой вариант, например - форум?)) Только не говорите: "смотри код" )))
     
  4. Elkaz

    Elkaz Старожил
    Команда форума Модератор

    С нами с:
    26 июн 2006
    Сообщения:
    3.373
    Симпатии:
    0
    Адрес:
    Баку, Азербайджан
    Kreker
    Как грамотнее - это не ко мне :)
    Просто скорее лучше искать по названию. Тут LIKE вполне справляется. А если уже внутри статьи (TEXT) - придется или FULLTEXT придумывать. Или можно еще организовать что-то вроде тегов для определенной статьи и искать по тегам :)
     
  5. Anonymous

    Anonymous Guest

    phpbb строит собственный индекс слов в сообщениях
     
  6. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    В общем делаю так, как все задумал, но тут же в ступоре оказался =\
    Создал таблицу, где `title` & `text` FULLTEXT, поместил туда текст, вот отрывок:
    Вот кусочек PHP (не удивляйтесь некоторым вещам, так надо, да на отсутствие необъявленых переменных тоже не обращайте внимание, там много незначимого кода для их определения):
    PHP:
    1. <?php
    2. if ($symbols <= 5) {
    3.             $query = 'SELECT * FROM `search` WHERE '.$where.' '.$ssection.$sort.$limit;
    4.             $result = $mysqli -> query($query)
    5.                                                 or mysqdie($mysqli->errno.'@'.$mysqli->error, $_POST["section"]);
    6.             $mtxt .= $query;
    7.         }
    8.         else if  ($symbols > 5) {
    9.             $query ='SELECT * FROM `search` WHERE '.$ssection.' MATCH('.$where.') AGAINST("'.$mysqli -> real_escape_string($word).'" IN BOOLEAN MODE)'.$sort.$limit;
    10.             $result = $mysqli -> query($query)
    11.                                                 or mysqdie($mysqli->errno.'@'.$mysqli->error, $_POST["section"]);
    12.             $mtxt .= $query;
    13.         }
    14.         else {
    15.             die($ptitle.'&&&strtitle2='.$ntitle.'&&&strtitle2='.$mtxt.'Пустой запрос');
    16.         }
    17.        
    18.         if ($result->num_rows > 0) {
    19.             $mtxt .= '<pre>';
    20.             function sdsdsd($buffer) {
    21.                 global $mtxt ;
    22.                 $mtxt .= $buffer;
    23.             }
    24.             $printer = "";
    25.            
    26.             while ($row = $result -> fetch_array(MYSQLI_ASSOC)) {
    27.                 ob_start("sdsdsd");
    28.                 print_r($row);
    29.                 ob_end_flush();
    30.             }
    31.             $mtxt .= '</pre>';
    32.         }
    33. ?>
    Если ввожу wallow, то выполняется полнотекстовый поиск, скрипт выдает :
    + результат запроса (выводит массив из базы (с текстом, где найдено слово)).

    Если ввожу wall, то должен искаться по шаблону LIKE, скрипт выдает:
    И все!

    Что за баг? Почему не выдает результата в случае LIKE?
     
  7. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Трындец я глуп %) У меня слово-то не в начале строки. Надо % и перед словом...
     
  8. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    Уверен что правильный.

    Одно непонятно, с какой целью используется LIKE?
     
  9. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Лайк используется в словах от 3х до 5 символов. 3 полнотекстовый не поддерживает, а когда мало символов не советуют вроде бы его использовать.
    Следующее на чем я заступорился - как определить в том же запросе и кол-во результатов? Склоняюсь к вложенным запросам...
     
  10. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    два запроса, count и выборка.
     
  11. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    ерунда, имхо, если у тебя все слова проиндексированы самостоятельно, то ты можешь индексировать хоть запятые.
    А искать LIKE'ом во всех строках - это уже дорогая операция. Гораздо быстрее найти точное соответствие оператором "=" в индексной таблице.

    Создай пожалуйста базу в 1 млн строк, каждая по 50 кб, и попробуй LIKE. Я не уверен что результат тебе понравится
    ( хотя грешным делом надо бы почитать как mysql оптимизирует LIKE заросы )

    Другое дело таблица с индексами: у тебя будет 30-50 тыс. проиндексированных слов, там уже можно и лайком :)
     
  12. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    ЕМНИП Для LIKE индекс будет использоваться только для шаблона вида
    Код (Text):
    1. aaa%
    Тоесть первые символы из строки.
     
  13. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Два раза выполняется поиск? =\ Или mysql сохранит результат предыдущего запроса?
    Да и вообще, для подсчета всех результатов надо будет искать по всей базе... Хотя я читал, что с лимитом тоже сначала
    ищется полностью выполняется запрос, а потом лимит его разбивает. :?
    topas
    У меня текст + тайтлы, причем тайтлы на 80% от всех строк будут пустыми =)
     
  14. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    да.
    неверно.
     
  15. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Неоптимально как-то =\
    Ладно, спасибо за ответы.
     
  16. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    Обоснуйте, пожалуйста
     
  17. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Первый запрос ищет до тех пор, пока результатов не наберется сколько нужно.
    Второй запрос ищет пока все не переберет и считает результаты.
    Вот это мне кажется не оптимальным.

    В идеале хотелось бы, чтобы перебирало все, считало результаты и отбирало часть необходимых. И все это одним запросом.
     
  18. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    так будет заметно дольше.
     
  19. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Почему? Что за парадоксальное явление?
     
  20. armadillo

    armadillo Активный пользователь

    С нами с:
    6 апр 2007
    Сообщения:
    2.380
    Симпатии:
    0
    Адрес:
    Russia, Moscow
    ну если у тебя не будет выборка на 90% от общего числа.

    count(*) хорошо оптимизирован по скорости. Он просто подсчитывает количество, не выбирая их и работает заметно быстрее выборки.
    Кроме того, запрос с count(*) часто можно упростить и ускорить.
     
  21. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    Kreker
    Я, наверное тупой... Или мы говорим о разных вещах

    Таблица с индексами:
    id
    name varchar(20)
    count int

    Таблица с текстом:
    id
    text text

    Таблица соответствий
    index_id
    text_id
    count
    weight (если хотите)
     
  22. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    topas
    Не, я, как уже писал, отдельно организовал таблицу для поиска.
     
  23. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    Kreker
    Тогда извините за пост непотеме