我有一个名为warehouse
类型下拉产品的自定义属性。
为了通过模型加载日期之间的Sku => Warehouse
(获得每个产品的指定值)更新;我做了以下事情:
// Load warehouse attribute options
$warehouse_options = array();
$options = array();
$attribute = Mage::getSingleton('eav/config')
->getAttribute(Mage_Catalog_Model_Product::ENTITY, 'warehouse');
if ($attribute->usesSource()) {
$options = $attribute->getSource()->getAllOptions(false);
}
$attribute = null;
foreach ($options as $option) {
$warehouse_options[$option['value']] = $option['label'];
}
$options = null;
// Load all products updated since last sync
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addAttributeToFilter('updated_at', array(
'from' => $datetime_from,
'to' => $datetime_to,
'date' => true
));
// Init results
$results = array(
'ServerDateTime' => $datetime_now,
'Mapping' => array()
);
// Build results
foreach ($collection as $p) {
$product = Mage::getModel('catalog/product')->load($p->getId());
$results['Mapping'][] = array(
'Sku' => $product->getSku(),
'Warehouse' => isset($warehouse_options[$product->getWarehouse()]) ? $warehouse_options[$product->getWarehouse()] : ''
);
$product = null;
}
$collection = null;
这很有效,但每个产品加载都很慢,所以如果我有3000
个产品,那就3000+
进行查询。
有没有办法优化这个,所以我可以用最少量的查询加载所需的数据&处理?
我尝试使用addAttributeToSelect
$collection->addAttributeToSelect('sku', 'warehouse');
但是,返回的$collection->getData()
不包含字段warehouse
。这是一个示例响应数组:
Array
(
[0] => Array
(
[status] => 1
[entity_id] => 4
[type_id] => simple
[attribute_set_id] => 4
[updated_at] => 2015-07-07 15:35:35
[sku] => C13S041061
)
答案 0 :(得分:1)
当你致电$collection->addAttributeToSelect('sku', 'warehouse');
时,你应该传递一个你想要的所有细节的数组,而不是作为单独的函数参数。
(看看Mage_Catalog_Model_Resource_Product_Collection::addAttributeToSelect($attribute, $joinType = false)
所以,你的电话应该是:
$collection->addAttributeToSelect(array('sku', 'warehouse'));
事实上,您应该可以致电:
$collection->addAttributeToSelect('warehouse');
因为SKU
应该是您指定的默认值。
这将允许您在循环中丢失额外的模型调用(这将真正杀死您的速度)。关于从这里开始的最佳方式,我个人最喜欢的是分页收藏。看看这里:http://www.douglasradburn.co.uk/dealing-with-large-collections-in-magento/
基本上,这样的事情(示例订单集合):
$ordersCollection = Mage::getModel('sales/order')->getCollection();
$ordersCollection->setPageSize(100);
$pages = $ordersCollection->getLastPageNumber();
$currentPage = 1;
do {
$ordersCollection->setCurPage($currentPage);
$ordersCollection->load();
foreach ($ordersCollection as $_order) {
// process
}
$currentPage++;
// clear collection (if not done, the same page will be loaded each loop) - will also free memory
$ordersCollection->clear();
} while ($currentPage < = $pages);