I am using Magento 2.2 and I want to get a collection of categories that is made up of a number of sublevels of a specific category. How can I get this collection sorted by both level and position so it matches the Magento backend?

I am currently getting a category collection with a variable depth by using this code:

$childCategories = $this->categoryCollectionFactory->create();
$childCategories->addPathsFilter($menuItemCategory->getPath() . '/');
$childCategories->addLevelFilter($menuItemCategory->getLevel() + $this->depthLevel);

Where $menuItemCategory is the base category that is configured, and $this->depthlevel the number of sublevels that should be in the collection.

As expected this generates a nice collection of all the categories I want. Except that they are sorted by level and id, not level and position like I want. And when I apply a sort of position it does not make any distinction between the levels and I end up with a mess.

I've been playing around with the trees/nodes of Magento as they seem to offer some extra/other functionality compared with the collection. But if its possible through this way, I haven't figured out how to do it.

I keep ending up creating a collection for each separate level of categories. But that feels way too cumbersome as a solution. Also, it pretty much cancels out the whole idea of having a variable for the depth level.

I feel a solution is not too far off, but I can't seem to figure it out. If someone can point me in the right direction that would be great!

1 Answer 1


Ok, spent almost another complete day figuring this one out. After trying all kinds of NodeFactories and TreeFactories I ended up doing a hail mary search through the whole codebase to check where, why and how the category tree is implemented by Magento itself.

This lead me to a cute little class: \Magento\Catalog\Model\CategoryManagement

That has the method getTree($rootCategoryId = null, $depth = null) which actually does exactly what i needed!

Put in the parent category you configured as root category and the depth you'd like as arguments and it will return a tree (not a collection!) of all the underlying categories. They are neatly sorted by level and by position, just as I wanted. And I didn't even have to generate multiple collections.

You can keep things clean and proper by inserting the \Magento\Catalog\Api\CategoryManagementInterface into your constructor.

Hope this will help to reduce the time spent searching and trying for other people!

Ps. The tree/node structure is partly covered by unit tests in the Magento core that can be pretty interesting and useful to figure out how they work. As there is no documentation on this afaik.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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