Magento 2 – find products without category
In this tutorial I show you how to find products without category in Magento 2, so called orphan products. Orphan products are products that are not connected to a category. If they are not visible by search, it is impossible to find them in frontend. For a monitoring script, it is a good idea to also find such products.
Magento 2 – find products without category
For my search, I use the following code snippet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | //get products without category $products = $this->_productCollectionFactory->create() //->addFieldToFilter('category_ids', "") ->addFieldToFilter('visibility', \Magento\Catalog\Model\Product\Visibility::VISIBILITY_BOTH) ->addFieldToFilter('status', \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) ->load(); if($products->getSize() > 0) { $orphanProducts = 0; foreach($products as $product) { $categories = $product->getCategoryIds(); if(count($categories) == 0) { ++$orphanProducts; $this->_importMonitoring->addError("Product " . $product->getSku() . " has no category."); } } $this->_importMonitoring->setProductsWithoutCategory($orphanProducts); } |
This code gets a collection of all products that are enabled and visible, so they should be visible, but are not traceable in your category tree. We step through this product collection and get all categoryIds for each product. If this list is empty, then we count it as orphan product. This code has two outputs, an error message with detailed information for each product and a number of counted products without category.
Monitoring
Depending on your needs, you can run this script:
- daily
if your customer creates and updates products - after import
if there is an import script that runs periodically
Conclusion
It is quite easy to build a simple monitoring script to find products without category. This helps you a lot to fix orphan products problem.
Hey there. Is there a way to get products without category with SQL or admin?
A simple SQL query for this is:
select * from catalog_product_entity where entity_id not in (select product_id from catalog_category_product)