Magento: how to merge two product collections into one?

if i have two product collections is there a way to merge them into one?

for example (my final intent isn’t to actually just get a collection of 2 cats, this is just to illustrate the issue):

$collection1 = Mage::getModel('catalog/category')->load(148)->getProductCollection();
$collection2 = Mage::getModel('catalog/category')->load(149)->getProductCollection();

$merged_collection = merge_collections($collection1,$collection2);

any help would be appreciated!

5 thoughts on “Magento: how to merge two product collections into one?”

  1. Assuming the items you wish to group together are of the same type and exist in the database then you can do this:

    $collection1 = Mage::getModel('catalog/category')->load(148)->getProductCollection();
    $collection2 = Mage::getModel('catalog/category')->load(149)->getProductCollection();
    
    $merged_ids = array_merge($collection1->getAllIds(), $collection2->getAllIds());
    // can sometimes use "getLoadedIds()" as well
    
    $merged_collection = Mage::getResourceModel('catalog/product_collection')
        ->addFieldToFilter('entity_id', array('in' => $merged_ids))
        ->addAttributeToSelect('*');
    

    Here I know to filter by entity_id because that is products’ key field, like it is for most entity types, some flat tables have a different primary key. Often you can generalise that with one of the collection’s getIdFieldName() method. Products are a bad example in this case because it’s ID field name isn’t filled out correctly.

  2. Almost every (or every?) collection in Magento inherits from a Varien Data Collection. A collection is a special object that holds objects of another type. There’s no method for merging collections, but you can add additional items of the appropriate type to the collection.

    Code like this should get you where you want to go, although there’s probably more efficient ways to loop and do the actual merging.

    $collection1 = Mage::getModel('catalog/category')->load(148)->getProductCollection();
    $collection2 = Mage::getModel('catalog/category')->load(149)->getProductCollection();
    
    //load an empty collection (filter-less collections will auto-lazy-load everything)
    $merged = Mage::getModel('catalog/product')->getCollection()->addFieldToFilter('entity_id',-1);
    
    //add items from the first collection
    foreach($collection1 as $item)
    {
        $merged->addItem($item);
    }
    
    //add items from the second collection
    foreach($collection2 as $item)
    {               
        //magento won't let you add two of the same thing to a collection
        //so make sure the item doesn't already exist
        if(!$merged->getItemById($item->getId())) 
        {
            $merged->addItem($item);
        }           
    }
    
    //lets make sure we got something
    foreach($merged as $product)
    {
        var_dump($product->getName());
    }
    

  3. I don’t think there is such a method, but you can probably do something like that :

    foreach ($collection1 as $item){
        $collection2->addElem($item);
    }
    

  4. you can filter your collection directly without using 2.

    $products = Mage::getModel('catalog/product');
    $_collection = $products->getCollection();
    ->addCategoryFilter(2)
    ->load();
    

    or try using ‘addItem’ to add your results to a collection. See also in Magento wiki

  5. for the collection of products of several categories, you can use the following code

          $collection = Mage::getModel('catalog/product')->getCollection()
            ->addAttributeToSelect('name')
            ->addAttributeToSelect('sku');
    
        $collection->getSelect()
            ->join(
                'catalog_category_product',
                'product_id=entity_id',
                array('category_id')
                )
            ->where('catalog_category_product.category_id IN (?)', $categories);
    

Leave a Reply

Your email address will not be published. Required fields are marked *