У меня есть заголовок (varchar), описание (текст), ключевые слова (varchar) в моей таблице mysql.
Я сохранил поле ключевых слов, поскольку я думал, что буду искать только в этой области. Но теперь мне нужно искать среди всех трех полей. поэтому для ключевых слов «word1 word2 word3» мой запрос становится
SELECT * FROM myTable WHERE ( name LIKE '%word1%' OR description LIKE '%word1%' OR keywords LIKE '%word1%' OR name LIKE '%word2%' OR description LIKE '%word2%' OR keywords LIKE '%word2%' OR name LIKE '%word3%' OR description LIKE '%word3%' OR keywords LIKE '%word3%') AND status = 'live'
Выглядит немного грязно, но это работает. Но теперь мне нужно реализовать поиск синонимов. поэтому для данного слова, предполагающего наличие нескольких синонимов, этот запрос становится более грязным, когда я просматриваю все слова. Поскольку требования становятся более ясными, мне нужно будет присоединиться к этой myTable и к некоторым другим таблицам.
Так
Считаете ли вы, что вышеупомянутый путь грязный и вызовет проблемы по мере роста данных?
Как я могу избежать беспорядка? Есть ли какое-нибудь более чистое решение, которое я могу пройти? Любой пример поможет мне.
С благодарностью
@Peter Stuifzand предложил мне, что я могу создать одну таблицу search_index и сохранить все 3 поля (название, ключевое слово, desc) на этом и выполнить полнотекстовый поиск. Я понимаю, что эта таблица также будет содержать ссылку на первичный ключ myTable.
Но мой расширенный поиск может включать в себя объединение mytable с таблицей Category, географической страницей (для поиска в пределах 10, 20 миль и т. Д.), Фильтрацией по некоторым критериям и, конечно, сортировкой результатов поиска. Считаете ли вы, что использование mysql fulltext не замедлит его?
Когда ваши запросы выходят из-под контроля, иногда лучше писать их части в SQL и других частях вашего выбранного языка программирования.
И вы также можете использовать полнотекстовый поиск для поиска. Вы можете создать отдельную таблицу со всеми полями, которые вы хотите найти, и добавить модификатор FULLTEXT
.
CREATE TABLE `search_index` ( `id` INT NOT NULL, `data` TEXT FULLTEXT, ); SELECT `id` FROM `search_index` WHERE MATCH(`data`) AGAINST('word1 word2 word3');
Еще один способ (иногда это лучше, но это зависит …)
SELECT id, name, description, keywords FROM myTable WHERE name REGEXP '.*(word1|word2|word3).*' OR description REGEXP '.*(word1|word2|word3).*' OR keywords REGEXP '.*(word1|word2|word3).*' ;
PS: Но MATCH(cols) AGAINST('expr')
возможно, лучше для вашего дела.
Если это вообще возможно, вы должны изучить полнотекстовый поиск .
Учитывая расширенные требования, вы можете захотеть рассмотреть возможность использования apache solr (см. http://lucene.apache.org/solr/), это факсированная поисковая система, предназначенная для полнотекстового поиска. Он имеет интерфейс RESTful, который может возвращать XML или JSON. Я использую его с несколькими проектами – хорошо работает.
Единственная область, в которой я вижу, что вы сталкиваетесь с некоторыми проблемами, потенциально связана с поиском близости, но с некоторой дополнительной логикой для построения запроса она должна работать.