Я разработал систему пользовательского поиска для нашего магазина Magento, и я пытаюсь загрузить коллекцию продуктов в очень определенном порядке (я оценил результаты в соответствии с разработанным мной алгоритмом).
Я могу правильно загрузить коллекцию продуктов, но это не тот порядок, в котором я бы хотел, чтобы он находился. Вот в основном, как он работает сейчас:
Мой запрос к базе данных в основном возвращается с массивом идентификаторов продуктов PHP. В этом примере можно сказать, что это выглядит так:
$entity_ids = array(140452, 38601 );
Теперь я могу транспонировать 140452 и 38601, и коллекция продуктов возвращается в том же порядке каждый раз. Я хотел бы, чтобы сбор продукта находился в том же порядке, что и идентификатор идентификаторов сущностей.
Код, который я использую для создания моей коллекции, выглядит следующим образом:
$products = Mage::getModel('catalog/product') ->getCollection() ->addAttributeToSelect('*') ->addAttributeToFilter('entity_id', array('in' => $entity_ids)) ->setPageSize($results_per_page) ->setCurPage($current_page) ->load();
Есть ли способ установить порядок сортировки как порядок массива $ entity_ids?
Коллекции наследуются от класса
Varien_Data_Collection_Db
В этом классе есть метод addOrder
.
public function addOrder($field, $direction = self::SORT_ORDER_DESC) { return $this->_setOrder($field, $direction); }
Итак, вы думаете, что что-то вроде этого должно работать для базового заказа
Mage::getModel('catalog/product') ->getCollection() ->addAttributeToSelect('*') ->addOrder('entity_id');
Однако это не так. Из-за сложного объединения, участвующего в EAV Collections, существует специальный метод, используемый для добавления атрибута в предложение заказа
Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection::addAttributeToSort
Однако снова это можно использовать только для добавления простых атрибутов. Чтобы создать произвольный вид, вам необходимо напрямую манипулировать объектом Zend_Select
. Я не большой поклонник этого, и я не большой поклонник использования пользовательских функций mysql для достижения чего-то, но, похоже, это единственный способ сделать это
Я проверил следующий код на складе и получил желаемые результаты. Вы должны использовать его, чтобы получить то, что хотите.
$ids = array(16,18,17,19); $products = Mage::getModel('catalog/product')->getCollection() ->addAttributeToSelect('*') ->addAttributeToFilter('entity_id',$ids); //shakes fist at PDO's array parameter $ids = array_map('intval', $ids); $products->getSelect()->order("find_in_set(e.entity_id,'".implode(',',$ids)."')"); foreach($products as $product) { var_dump($product->getEntityId()); var_dump($product->getSku()); }
Нет никакого способа сортировать произвольно в SQL, поэтому вам придется сортировать результаты в PHP впоследствии. Тогда большая проблема заключается в том, что вы используете размер страницы, чтобы ограничить количество возвращаемых результатов, некоторые из записей, которые вы хотите, могут не возвращаться из-за этого.
Лучшее решение – добавить атрибут к продуктам, которые затем можно использовать для сортировки. Продукты в категориях уже имеют значение «позиция», которое используется таким образом. Затем вам нужно использовать метод addOrder()
addAttributeToSort()
, предложенный Аланом, но с вашим пользовательским атрибутом.
(Объяснение торопится, дайте мне знать, если не достаточно ясно)