SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 29.06.2011 22:17:47

Syegorius
Завсегдатай
Зарегистрирован: 29.10.2010
Сообщений: 28

Полнотекстовый поиск

Доброе время суток. Есть две таблицы:

CREATE TABLE IF NOT EXISTS `songs_rating` (
  `rating` int(10) NOT NULL,
  `s` varchar(1) NOT NULL,
  `id` int(10) NOT NULL,
  `user_id` int(10) NOT NULL,
  `name` varchar(127) NOT NULL,
  `author` varchar(93) NOT NULL,
  `goals` varchar(32) NOT NULL,
  `approve` tinyint(1) NOT NULL,
  `tags` varchar(127) NOT NULL,
  KEY `rating` (`rating`),
  KEY `goals` (`goals`),
  KEY `goals_2` (`goals`),
  FULLTEXT KEY `name` (`name`,`author`,`goals`,`tags`),
  FULLTEXT KEY `tags` (`tags`),
  FULLTEXT KEY `goals_3` (`goals`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
INSERT INTO `songs_rating` (`rating`, `s`, `id`, `user_id`, `name`, `author`, `goals`, `approve`, `tags`) VALUES
(500, 'b', 2, 5, 'Do my job id 2', 'Yegor SY Zhdanov Yegor SY Zhdanov Yegor SY Zhdanov', 'sale', 1, 'love, hate, memory, helo, hi, word, world, mama, tree, memory, sky, branch, table, lamp, light')

и

CREATE TABLE IF NOT EXISTS `songs_b` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `text` text NOT NULL,
  `music` text NOT NULL,
  `voice` text NOT NULL,
  `user_id` int(10) NOT NULL,
  `rating` int(10) NOT NULL,
  `goals` varchar(32) NOT NULL,
  `approve` tinyint(1) NOT NULL,
  `tags` varchar(255) NOT NULL,
  `is_top` tinyint(1) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`,`rating`),
  KEY `is_top` (`is_top`),
  FULLTEXT KEY `tags` (`tags`),
  FULLTEXT KEY `goals` (`goals`),
  FULLTEXT KEY `name` (`name`,`goals`,`tags`)
) ENGINE=MyISAM  DEFAULT CHARSET=cp1251 AUTO_INCREMENT=10 ;
INSERT INTO `songs_b` (`id`, `name`, `text`, `music`, `voice`, `user_id`, `rating`, `goals`, `approve`, `tags`, `is_top`) VALUES
(1, 'Do my job', 'This is song content for do my job', '', '', 5, 450, '', 0, 'love, rain, autumn, yellow leaf, pain', 0)

Вот этот запрос работает нормально:
select * from songs_rating where match (tags) against ('love') limit 0, 10
а этот ничего не ввыводит:
select * from songs_b where match (tags) against ('love') limit 0, 10
Подскажите в чем дело пожалуста.

Заранее спасибо!

Неактивен

 

#2 30.06.2011 14:40:29

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Полнотекстовый поиск

А общее количество строк то какое? Может быть, просто любовь — это
стопслово для этого набора песен?

Неактивен

 

#3 30.06.2011 16:01:37

Syegorius
Завсегдатай
Зарегистрирован: 29.10.2010
Сообщений: 28

Re: Полнотекстовый поиск

я пробовал с другими словами, в первом случае всегда находит а во втором пусто. А что значит общее количество строк? если типа сколько записей в таблице, то 9-10 в обоих.

Неактивен

 

#4 30.06.2011 16:25:14

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Полнотекстовый поиск

С одинаковыми данными? Общее количество строк влияет сильно на полнотекстовый
поиск:

Код:

[silentia] root test > CREATE TABLE ft (a TEXT, FULLTEXT(a));
Query OK, 0 rows affected (0.00 sec)

[silentia] root test > INSERT INTO ft VALUES ('alpha'), ('beta'), ('gamma');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

[silentia] root test > SELECT * FROM ft WHERE MATCH (a) AGAINST ('beta');
+------+
| a    |
+------+
| beta |
+------+
1 row in set (0.00 sec)

[silentia] root test > INSERT INTO ft VALUES ('another beta'), ('yet another beta'), ('and a third beta');
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

[silentia] root test > SELECT * FROM ft WHERE MATCH (a) AGAINST ('beta');
Empty set (0.00 sec)

Происходит из-за того, что слово встречается очень часто в таблице: такое
слово считается стопсловом и выбрасывается из индекса.

Неактивен

 

#5 30.06.2011 17:14:01

Syegorius
Завсегдатай
Зарегистрирован: 29.10.2010
Сообщений: 28

Re: Полнотекстовый поиск

блин, и в правде... А как быть в таких случаях... вообще кто-то может скинуть ссылку или еще че-то что б почитать подробно про полнотекстовый поиск, то что я находил в нете там буквально описывается в общем... или скажите как еще можно осуществить поиск текста не применяя полнотекстовый поиск...
like наверно не подойдет потому что будет долго искать?

Неактивен

 

#6 30.06.2011 17:20:11

Syegorius
Завсегдатай
Зарегистрирован: 29.10.2010
Сообщений: 28

Re: Полнотекстовый поиск

вообще было бы интересно как осуществляют свой поиск поисковики... если у кого есть ссылки то тож дайте почитать

Неактивен

 

#7 30.06.2011 17:43:56

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Полнотекстовый поиск

Как правило, поиск используют тогда, когда нужно найти немного
документов из большого их количества. Для того, чтобы на поиск
«Маша и медведь» искались только Маша с медведем (без «и») и
была придумана схема со стопсловами, это вполне себе хорошая
практика smile Думаю, Вам просто нужно дозаполнить базу.

Без полнотекстового индекса — можно построить отдельное дере-
во тегов и табличку многие-ко-многим связей с документами.

Поисковики используют, как правило, свои собственные алгоритмы
построения индексов.

Неактивен

 

#8 01.07.2011 18:13:53

Syegorius
Завсегдатай
Зарегистрирован: 29.10.2010
Сообщений: 28

Re: Полнотекстовый поиск

господа, если еще кто-то читает эту тему, то посоветуйте логична ли реализация поиска текста таким образом: из первой таблицы которую я приводил выше сделать две:

1 - songs_rating, в которой будут все поля кроме tags, goals;
2 - songs_tags, в которой будет три поля rating, tags и songs_rating_id. В поле tags будут храниться теги разбитые скриптом по пробелу или по запятой, т. е. в одной ячейке - одно слово, в ячейке songs_rating_id будет хранится его id в songs_rating. в поле rating - рейтинг песни.
полю tags я ставлю обычный индекс, плюс я ставлю индекс для tags и rating.

поиск будет осуществятся так:

select * from songs_rating where id  in (select id from songs_tags where tags like "введенное_пользователем_слово%" order by rating desc limit 0, 10)

Скажите есть ли смысл в таком поиске, если в одной только таблице songs_rating будет сотни тысяч записей, а в songs_tags раз в десять больше? Плюс мне нужно ко всему еще и узнать количество всех возможных попаданий для "введенное_пользователем_слово%", т. е. к этому запросу добаляется еще один такой:

select count(*) from songs_tags where tags like "введенное_пользователем_слово%";

спасибо за ваши советы!

Неактивен

 

#9 01.07.2011 18:33:53

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Полнотекстовый поиск

Если тегов будет немного — имеет смысл. Если Вы туда собираетесь засунуть все
слова всех песен, то идеально будет работать обычный полнотекстовый поиск.

Неактивен

 

#10 01.07.2011 19:07:32

Syegorius
Завсегдатай
Зарегистрирован: 29.10.2010
Сообщений: 28

Re: Полнотекстовый поиск

слова песен я туда не собираюсь засовывать) тегов примерно 5-10 на одну песню, плюс ее название это примерно еще 2-5 слов итого на одну песню выйдет где-то 5-15 записей...

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson