4

Given a $product, I need to get a random collection of 10 products belonging to the same categories of $product with a similar price - let's say +-15% the price of $product.

My idea is to get all product's $categories, then load a $cat_products collection for each category, then loop over $cat_products and check each $cat_product against my price condition and eventually add the $cat_product to an array if it matches. Then return the array.

$categoryIds = $product->getResource()->getCategoryIds($product);

foreach ($categoryIds as $categoryId) {
    $cat_products = Mage::getModel('catalog/category')->load($categoryId)
        ->getProductCollection()
        ->addAttributeToFilter('status', 1)

    foreach ($cat_products as $cat_product) {
        // check against my price conditions
    }
}

I didn't try it yet, but it should work. It looks extremely inefficient, though (also, I have a large catalog with many categories, and many categories - especially roots categories - are shared among products, so I would end up loading a few hundred thousands of products ...).

Any idea how can I get same result in a more efficient way?

4

I think this is what you want.

$categoryIds = $product->getResource()->getCategoryIds($product);
$price = $product->getPrice();
$priceVriation = 15; // Percent Value for Variation

$minLimit = $price - ($price*$priceVriation)/100;
$maxLimit = $price + ($price*$priceVriation)/100;

$collection = Mage::getResourceModel('catalog/product_collection')
->joinField('category_id','catalog/category_product','category_id','product_id=entity_id',null,'left')
->addAttributeToFilter('category_id', array('in' => $categoryIds))
->addAttributeToSelect('*');
$collection->addFinalPrice();
$collection->getSelect()->where("price_index.price <= $maxLimit AND price_index.price >= $minLimit")->group('e.entity_id')->limit(10)->order(new Zend_Db_Expr('RAND()'));

foreach($collection as $_product){
    echo $_product->getName()." with price = ". $_product->getPrice(). "<br>";
}

Total Execution Time: 0.16790199279785 Seconds

Output:

My Product Price = 400.0000
Min Limit Price = 340
Max Limit Price = 460

Similar Price Products

Linen Blazer with price = 455.0000
Linen Blazer with price = 455.0000
Linen Blazer with price = 455.0000
Convertible Dress with price = 340.0000
Convertible Dress with price = 340.0000
Convertible Dress with price = 340.0000
Convertible Dress with price = 340.0000
Convertible Dress with price = 340.0000
Madison LX2200 with price = 425.0000
Linen Blazer with price = 455.0000
  • awesome! +1 for the complete answer :) it works 'out of the box'. Just a question: how the 10 products are picked? first 10, randomly, ...? – davideghz Apr 4 '17 at 9:30
  • Currently they are picked randomly. Because it will get products from all categories and then will get first 10 products from collection. But it won't change sequence if you refresh page. – Jaimin Sutariya Apr 4 '17 at 9:43
  • 1
    Check updated code, now it will get 10 products randomly from collection and will change on each refresh. – Jaimin Sutariya Apr 4 '17 at 9:47
  • How would you edit the getSelect() query in order to get products that belong to all the product's categories at the same time? I created an ad-hoc Q here magento.stackexchange.com/questions/167561/… – davideghz Apr 4 '17 at 11:02
  • Okay, I'll check and update you for the same – Jaimin Sutariya Apr 4 '17 at 11:11
1

You can use price range filter in product collection Like :

$categoryId = 2;
$cat_products = Mage::getModel('catalog/category')->load($categoryId)
    ->getProductCollection()
    ->addAttributeToFilter('status', 1)
->addFieldToFilter('price', 
 array(array('from'=>'0','to'=>'50'))
 );

You can also calculate from and to price from current product price like

$fromPrice = $product->getPrice()-15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.