В версии плагина 3.x — добавилось много новых вариантов организовать поиск и сортировку объявлений. Коротко о новых возможностях:
- поиск простой: равенство перемененная = значение*
- поиск с условием: больше, меньше, больше или равно, меньше или равно, не равно.
- поиск по интервалу: например переменная должна быть от 4 и до 23 MySQL оператор BETWEEN
- поиск по заданному множеству: IN
- и долго думал, но все таки добавил поиск подстроки в тексте регулярным выражением rlike
- сортировка результата (туда\обратно) простая и сортировка с конвертацией значения в число CAST($sqlNameVar AS SIGNED)
Я рассчитываю на аудиторию, которая уже понимает как работают выше перечисленные операторы, объяснять основы SQL здесь я не буду.
Прежде чем начинать начинать работать с поиском его надо включить в админке плагина есть галочка. В качестве рабочих примеров я буду использовать свой новый проект он очень показателен так как задействует практически все возможности плагина, здесь много полей данных и собственно говоря новая версия была написана специально для него.
Поиск можно осуществлять либо через GET запрос, то есть сформировать соответствующий URL (ссылку), либо по средствам POST отправив данные через форму поиска.
Простейший пример:
Найти записи в которых ads_quality (качество видео) равно HDRip.
Однако след пример сработает не совсем так как вы ожидаете:
В результате найдутся все записи в которых есть вхождение rip причем регистр не учитывается, это есть не что иное как SQL оператор LIKE причем выражение взято в проценты вот так — $sqlNameVar LIKE ‘%$value%’. В предыдущих версиях плагина я решил, что от простого знака равно толку мало и поставил LIKE, ну так оно и осталось пока — жалоб не поступало, и практика показала, что так намного функциональные. Теперь, когда мы знаем про оператор LIKE давайте найдем все фильмы с 6 канальным звуком (6 ch), для звуковых параметров у нас выделено спец метаполе ads_audio получаем:
SQL: ads_audio.meta_value LIKE ‘%6 ch%’
По открывайте полученные записи и проверьте — везде в поле Аудио будет присутствовать подстрока 6 ch.
Перейдем к условиям. Найдем все фильмы в которых IMDb рейтинг больше 8
SQL: ads_imdb_rating.meta_value > 8
Поскольку http протокол плохо переносит, когда в URL всякие значки типа < > = пришлось заменить их на спец слова, такой вот финт ушами :). Общий принцип построения URL таков:
имя_переменной[оператор]=значение
Привожу таблицу соответствия этих слов и операторов SQL:
more | > (больше) |
less | < (меньше) |
moe | >= (больше или равно) |
loe | <= (меньше или равно) |
ne | ( не равно ) |
between | BETWEEN (проверка диапазона) |
in | IN (принадлежность к множеству) |
rlike | rlike (регулярные выражения) |
Пример с between зададим условие — найти фильмы продолжительность которых от менее 1 часа. Поскольку продолжительность хранится в минутах переводим в минуты и составляем URL:
SQL: adp_ads_duration BETWEEN 0 AND 60
adp_file_size[between][0]=629145600 — так мы задаем нижний предел
adp_file_size[between][1]=786432000 — а так верхний
немного громоздко, но работает.
Пример с IN (принадлежность к множеству), давайте попробуем найти все фильмы хорошего качества HDRip, DVDRip и BDRip :
SQL: ads_quality.meta_value in (‘HDRip’,’DVDRip’,’BDRip’)
Пример с rlike приводить не буду.
Комбинирование условий
Условия можно комбинировать как угодно:
Найти фильмы из категории Документальные (id категории = 32), у которых качество = DVDRip и размер больше либо равно 700 MB (700*1024*1024)
Механизм работы:
За обработку поисковых запросов отвечает функция function ads_queryfilter($query) если поиск идет по мета полю (ads_), то к основному запросу присоединяется LEFT JOIN таблица wp_postmeta и так для каждой переменной ads_. Для поля adp_ ничего присоединять не надо так-как они уже находятся в составе таблицы wp_posts
Теперь скажу самое главное — для каждой переменной можно назначить свою пользовательскую функцию, имя функции должно начинаться с названия переменной и суфикса _query. Так для переменной ads_quality можно назначить свою функцию которая должна вернуть правильный SQL текст с условием поиска и обязательное условие в тексте должен первым идти оператор AND:
function ads_quality_query($value){
.........
return ' AND '. ваше условие поиска;
}
Лучше примеров пояснений нет — на сделаем альтернативу оператору between для поиска фильмов размером указным в формате x:y (MB), предварительно надо открыть секрет размер файлов на сохраняется в байтах значит переводим наши значения в байты x*1024*1024 (нижний предел) и y*1024*1024 = 786432000 (верхний предел):
для этого в ads_config.php добавляем следующую функцию:
function adp_file_size_query($var){
list($x,$y) = explode(':',$var);
$x = (int)$x*1024*1024;
$y = (int)$y*1024*1024;
$sql_where = " AND ( adp_file_size >= $x AND adp_file_size <= $y ) ";
return $sql_where;
}
Если вы используете мета поле ads_ тогда к переменной надо обращатся как имя_поля.meta_value например : ads_quality.meta_value
Сортировка
Чтобы задать сортировку записей по какому либо полю используйте след синтаксис:
ads_order[ads_name_var]='sort' где
ads_name_var имя поля по которому вы хотите задать сортировку;
sort указание типа сортировки может принимать след значения : asc, desc, iasc, idesc;
Например отсортируем записи по полю ads_quality
SQL: ORDER BY ads_quality.meta_value ASC
Как я уже говорил выше, кроме простой сортировки есть сортировка с принудительной конвертацией значений к числу. Дело в том, что в мета полях, если вы записываете число то оно сохраняется как строка т.к. тип столбца строковый, поэтому если в мета поле хранится число то надо использовать вместо asc iasc. Отсортируем фильмы по рейтингу IMDb:
SQL: CAST(ads_imdb_rating.meta_value AS BINARY) ASC
Ну и напоследок, хочу обратить выше внимание на замечательную функцию worpdpress при конструировании url ссылок может сильно облегчить вашу задачу.
Пытаюсь разобраться с поиском, ошибка всплывает, может подскажите с чем связана?
Например, такой запрос:
?ads_price[between][0]=0&ads_price[between][1]=2000
и вот что выдает wordpress:
WordPress database error: [Unknown column ‘wp_posts.ID’ in ‘on clause’]
SELECT SQL_CALC_FOUND_ROWS wp_posts.* FROM wp_posts LEFT JOIN wp_postmeta ads_price ON (wp_posts.ID = ads_price.post_id) WHERE 1=1 AND wp_posts.ID NOT IN ( SELECT tr.object_id FROM wp_term_relationships AS tr INNER JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id LEFT JOIN wp_postmeta ads_price ON (wp_posts.ID = ads_price.post_id) WHERE tt.taxonomy = ‘category’ AND tt.term_id IN (‘1′) ) AND wp_posts.post_type = ‘post’ AND (wp_posts.post_status = ‘publish’) AND ads_price.meta_key = ‘ads_price’ AND ads_price.meta_value BETWEEN 0 AND 2000 ORDER BY wp_posts.post_date DESC LIMIT 0, 3
сегодня проверил поиск и немного поменял примеры в статье, все нормально работает, у вас какой-то слишком сложный запрос с подзапросом наверно неправильно подставляются строки с условиями в основной запрос, но переделывать пока, что лень
А как можно выбрать в массив все значения какой нибудь переменной ads_test из постов определенной категории?
ну если вы уверенны что правильно спросили то вам надо тогда писать SQL запрос в таблицу SLECT wp_meta WHERE meta_key = ‘ads_test’
примерно как то так вернет вам все мета поля ads_test, ах да еще категорию надо… — ну это уже посложнее будет это только за пиво.
ну а если все таки надо получить все записи из категории и где есть метаполе ads_test тогда мона воспользоваться описанным выше методом
Здравствуйте!
Хочу сделать сортировку по возрастанию по полю ads_price.
?ads_order[ads_price]=asc
В результате этого получаю следующее. Сравниваются первые цифры, если совпадают то сортировка по второму числу: 30 больше 23, 33 больше 32, тут все нормально. Но вот порядок числа вообще никак не учитывается
скажем получается что 9 больше чем 100, а 1200 получится больше 10000. Может сможете прояснить ситуацию.
http://ili.com.ua/wordpress/poisk-po-proizvolnyim-polyam.html — вот тут все прокоментировано
прочитайте параграф Сортировка
в вашем случае надо ипользовать преобразованеи строки в число
поэтому задействуем
?ads_order[ads_price]=iasc
Я обратил внимание на это первоначально и пробовал использовать iasc, idesc однако результат получался такой же, что и asc, desс. Ка будто не работает преобразования поля к числу.
может MySQL не поддерживает преобразование выполняется через:
CAST($sqlNameVar AS BINARY) ASC
я вам посоветую для начала вывести результирующий запрос откройте ads.php
и найдите функцию ads_queryfilter
в конце перед return
распечатайте $query
print_r($query);
потом попробуй поиграться с ним прямо в phpMyAdmin
ну как то так
или другой вариант используйте не ads_ поля, а adp_ добавьте нужные вам числовые столбцы непосредственно в таблицу wp_posts например adp_price
сортировка будет работать
Попробовал второй вариант, заработало корректно, спасибо
A count можно как-то реализовать?
$postCount; как вариант, но что делать если постраничная розбивка?
$numposts = $wp_query->found_posts;
echo $numposts;
с сортировкой тоже проблемы, буду пробовать adp_
Можно прокомментировать условия проверки на NULL isnull и notnull. Если мне нужно отфильтровать только объявления с загруженными фотками, я должен прописать adp_picture[notnull]?
как можно сделать переменную флаг загрузки файлов, чтобы потом можно было отфильтровать объявления с фото. Сделал, но для того чтобы она приняла правильное значение нужно дважды обновлять объявления, в первый раз загрузятся файлы а во второй сделается проверка. Но это неправильно
если включена опция Применить шаблоны постов, то все что нужно сделать это проверить наличие файлов в масиве $post->files[0] — это первый файл будет
isnull трансформируется в SQL функцию ISNULL(sqlNameVar)
а notnull в NOT ISNULL(sqlNameVar) вот собственно и все
большие сложности и путаница возникает когда sqlNameVar = 0 и нам надо проверить пустое значение или там что-то есть
в MySQL значение 0 не значить null а вот php считает их равными
Как то там я делал через фильтры??? … вспомню напишу
Поиск работает только если в настройках WP Чтение-На главной странице отображать-Ваши последние записи.
А что делать если у меня в качестве главной страницы стоит Постоянная страница?
у меня вот так переключается
прошу пояснить, как это должно работать?
1. В качестве главной страницы у меня постоянная страница
2. ЧПУ стоит /%category%/%post_id%/
3. Поиск по метаполям — разрешен
делаю поиск например: /?ads_buldyear=1981
показывает постоянную ссылку и все ((
этот код добавляется в functions.php в папке темы
а для вашего случая тогда будет так
естественно шаблон search.php должен присутствовать в текущей теме
Столкнулась с проблемой как у edoroff. Имею почти тоже самое
1. В качестве главной страницы у меня постоянная страница
2. ЧПУ по умолчанию
3. Поиск по метаполям – разрешен
4. В function.php темы добавлен код с $_REQUEST[‘ads_url’]
делаю поиск например: /?ads_url=610000
(использую поле url для цены, и конечно редактировала form_templ…. и post_templ… в соответствии, но не думаю, что это могло затронуть queryfilter)
показывает главную постоянную страницу, но при этом добавляет к ней строку «Результаты поиска:» и метаданные главной страницы, которых нет при обычном построении страницы.
Убираю с главной страницы постоянную стр., убираю доп.код из function.php — результатов не выдает, лишь меняются строчки с надписами «нет результатов», что заставляет думать, что просто ни одна запись не подпадает под мой запрос. Крутила строку запроса под разными углами — ничего.
Может в search.php что не так? В основе используется стандартный шаблон последнего WP — twentyten
ух проблемы с этим поиском выдаю рабочую версию
1) создаем в корне сайта! файл search.php с таким кодом
в function.php темы
тоесть получается так если в url присутствует search.php значит переключаемся на шаблон поиска который search.php в текущей теме
теперь url для поиска должен выглядеть
или вот так посложнее
запсиси должны быть одновременно в категории 10(продажа) и 45 (Одесса)
верхний предел цены установлен до 60000 и сортировка задана по цене — возрастание
к сожалению и этим методом не сработало. вопрос цены пока не стоит так резко, потому буду решать его чуть позже, а поиск по пересекающимся категориям я решила на основе relevanssi плагина (надстройка над поиском) осталось лишь следить, чтобы названия категорий не попадались в постах, которые не относятся к этим категориям, и в данном проекте это реально.
Здравствуйте! Подскажите пожалуйста где нужно прописать ?ads_order[ads_price]=iasc чтобы сортировка по числу шла?