Добрый день, пишу для сайта умный фильтр по аналогии Яндекс.Маркета. Собственно уже который день озадачился вопросом реализация релятивного фильтра.
Что имеем:
Динамическую форму: (Форма генерируется автоматически, но для наглядности вставил HTML)
<form method="get" action="">
<div>
<label>Asus</label>
<input type="checkbox" name="filter[]" value="Asus">
<label>Acer</label>
<input type="checkbox" name="filter[]" value="Acer">
<label>Lenovo</label>
<input type="checkbox" name="filter[]" value="Lenovo">
</div>
<div>
<label>2015</label>
<input type="checkbox" name="filter[]" value="2015">
<label>2014</label>
<input type="checkbox" name="filter[]" value="2014">
<label>2013</label>
<input type="checkbox" name="filter[]" value="2013">
</div>
<button>Искать</button>
</form>
После сабмита формы имеется url следующего вида:
site.com?filter=Asus&filter=2015
Так же имеем таблицы в базе данных:
products (id, title)
products_to_filter (id, product_id, filter_id)
Сам обработчик выглядит следующим образом (P.S фреймворк Laravel)
Выборка соответствующих фильтров.
$filter[] = explode(',', $request->input('filter');
$filters = DB::table('products_to_filter')->whereIn('id', $filter)
->get()
->all();
foreach($filters as $row) {$filterArray[] = $row->product_id;}
Выборка продуктов:
$products = DB::table('products')->whereIn('id', $filterArray)->get()->all();
Собственно моя проблема заключается в следующем, фильтр работает, но не совсем так как мне нужно, тобишь при фильтрации, он должен результаты уменьшать, а он же наоборот ищет более углубленно, и как следствие увеличивает кол-во результатов. Как решить данную проблему?
Вы неправильно формируете $filterArray
- слишком это все просто. Сейчас условие которое вы получате звучит так:
Выбрать product_id
, которые соответствуют хотя бы одному выбранному пункту
Если вы поменяете логику на
Выбрать product_id
, которые соответствуют всем выбранным пунктам
то это тоже будет ошибкой (ну ведь не может же быть у одного и того же продукта производителем и Acer и Asus). В саму идею построения формы вкралась ошибка. Пункты (фильтры) нужно собирать в группы (производитель, год выпуска и т. д). И логика построения $filterArray
должна звучать так:
Выбрать product_id
, которые соответствуют всем выбранным группам фильтров. Соответствие группе - это соответствие хотя бы одному из фильтров группы.
Дополнено Я не очень силен в Laravel но идея вот такая:
// Допустим получаем из формы массив вот такого вида
$filtersgroup = array(
'manufacturer' => array(21, 22, 23),
'year' => array(37, 48),
'type' => array(51, 54, 59),
);
// Для построения запроса нам понадобится иметь номера таблиц, для связи с первой
$ix = 1;
foreach ($filtersgroup as $filtersId) {
$alias = 'pf' . $ix;
if (1 == $ix) {
$query = DB::table('product_to_filter AS pf1');
} else {
// Каждую последующую таблицу связываем с первой
$query = $query->join('product_to_filter AS ' . $alias,
'pf1.product_id',
'=',
$alias . '.product_id');
}
// Добавляем условие для каждой группы
$query = $query->whereIn($alias . '.product', $filtersId);
$ix += 1;
}
// Выполняем запрос, получаем список product_id
$filterArr = $query->select('pf1.product_id')->distinct()->pluck('product_id')}
В принципе можно добавить первой таблицу products
и получать в результате запроса уже готовый список "продуктов"
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Пытаюсь использовать готовый php скрипт для загрузки аватарок на сервер
Установил через composer библиотеку php-google-spreadsheet-client для работы с google таблицамиПри попытке обратится к таблице получаю ошибку