diff --git a/vendor/magento/module-catalog-graph-ql/Model/Resolver/Products/DataProvider/ProductSearch.php b/vendor/magento/module-catalog-graph-ql/Model/Resolver/Products/DataProvider/ProductSearch.php
index 13bd29e83d8..7475763be5a 100644
--- a/vendor/magento/module-catalog-graph-ql/Model/Resolver/Products/DataProvider/ProductSearch.php
+++ b/vendor/magento/module-catalog-graph-ql/Model/Resolver/Products/DataProvider/ProductSearch.php
@@ -8,6 +8,7 @@ declare(strict_types=1);
 namespace Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider;

 use Magento\Catalog\Api\Data\ProductSearchResultsInterfaceFactory;
+use Magento\Catalog\Model\Product\Visibility;
 use Magento\Catalog\Model\ResourceModel\Product\Collection;
 use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
 use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product\CollectionPostProcessor;
@@ -18,6 +19,7 @@ use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\SearchResultAp
 use Magento\Framework\Api\Search\SearchResultInterface;
 use Magento\Framework\Api\SearchCriteriaInterface;
 use Magento\Framework\Api\SearchResultsInterface;
+use Magento\Framework\App\ObjectManager;
 use Magento\GraphQl\Model\Query\ContextInterface;

 /**
@@ -55,6 +57,11 @@ class ProductSearch
      */
     private $searchCriteriaBuilder;

+    /**
+     * @var Visibility
+     */
+    private $catalogProductVisibility;
+
     /**
      * @param CollectionFactory $collectionFactory
      * @param ProductSearchResultsInterfaceFactory $searchResultsFactory
@@ -62,6 +69,7 @@ class ProductSearch
      * @param CollectionPostProcessor $collectionPostProcessor
      * @param SearchResultApplierFactory $searchResultsApplierFactory
      * @param ProductCollectionSearchCriteriaBuilder $searchCriteriaBuilder
+     * @param Visibility $catalogProductVisibility
      */
     public function __construct(
         CollectionFactory $collectionFactory,
@@ -69,7 +77,8 @@ class ProductSearch
         CollectionProcessorInterface $collectionPreProcessor,
         CollectionPostProcessor $collectionPostProcessor,
         SearchResultApplierFactory $searchResultsApplierFactory,
-        ProductCollectionSearchCriteriaBuilder $searchCriteriaBuilder
+        ProductCollectionSearchCriteriaBuilder $searchCriteriaBuilder,
+        Visibility $catalogProductVisibility
     ) {
         $this->collectionFactory = $collectionFactory;
         $this->searchResultsFactory = $searchResultsFactory;
@@ -77,6 +86,7 @@ class ProductSearch
         $this->collectionPostProcessor = $collectionPostProcessor;
         $this->searchResultApplierFactory = $searchResultsApplierFactory;
         $this->searchCriteriaBuilder = $searchCriteriaBuilder;
+        $this->catalogProductVisibility = $catalogProductVisibility;
     }

     /**
@@ -106,6 +116,9 @@ class ProductSearch
             $this->getSortOrderArray($searchCriteriaForCollection)
         )->apply();

+        $collection->setFlag('search_resut_applied', true);
+
+        $collection->setVisibility($this->catalogProductVisibility->getVisibleInSiteIds());
         $this->collectionPreProcessor->process($collection, $searchCriteriaForCollection, $attributes, $context);
         $collection->load();
         $this->collectionPostProcessor->process($collection, $attributes);
diff --git a/vendor/magento/module-catalog-graph-ql/Model/Resolver/Products/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilter.php b/vendor/magento/module-catalog-graph-ql/Model/Resolver/Products/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilter.php
index 0cc00bb7b32..b03d1bd068b 100644
--- a/vendor/magento/module-catalog-graph-ql/Model/Resolver/Products/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilter.php
+++ b/vendor/magento/module-catalog-graph-ql/Model/Resolver/Products/SearchCriteria/CollectionProcessor/FilterProcessor/CategoryFilter.php
@@ -9,6 +9,7 @@ namespace Magento\CatalogGraphQl\Model\Resolver\Products\SearchCriteria\Collecti

 use Magento\Catalog\Model\CategoryFactory;
 use Magento\Catalog\Model\ResourceModel\Category as CategoryResourceModel;
+use Magento\Catalog\Model\ResourceModel\Product\Collection;
 use Magento\Framework\Api\Filter;
 use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface;
 use Magento\Framework\Data\Collection\AbstractDb;
@@ -18,6 +19,36 @@ use Magento\Framework\Data\Collection\AbstractDb;
  */
 class CategoryFilter implements CustomFilterInterface
 {
+    /**
+     * Equal
+     */
+    private const CONDITION_TYPE_EQ = 'eq';
+
+    /**
+     * Not Equal
+     */
+    private const CONDITION_TYPE_NEQ = 'neq';
+
+    /**
+     * In
+     */
+    private const CONDITION_TYPE_IN = 'in';
+
+    /**
+     * Not In
+     */
+    private const CONDITION_TYPE_NIN = 'nin';
+
+    /**
+     * Supported condition types
+     */
+    private const CONDITION_TYPES = [
+        self::CONDITION_TYPE_EQ,
+        self::CONDITION_TYPE_NEQ,
+        self::CONDITION_TYPE_IN,
+        self::CONDITION_TYPE_NIN,
+    ];
+
     /**
      * @var CategoryFactory
      */
@@ -51,26 +82,46 @@ class CategoryFilter implements CustomFilterInterface
      */
     public function apply(Filter $filter, AbstractDb $collection)
     {
-        $conditionType = $filter->getConditionType();
-        if ($conditionType !== 'eq') {
-            return true;
-        }
-
-        $categoryIds = $filter->getValue();
-        if (!is_array($categoryIds)) {
-            $categoryIds = [$categoryIds];
-        }
-
-        $categoryProducts = [];
-        foreach ($categoryIds as $categoryId) {
-            $category = $this->categoryFactory->create();
-            $this->categoryResourceModel->load($category, $categoryId);
-            $categoryProducts[$categoryId] = $category->getProductCollection()->getAllIds();
-            $collection->addCategoryFilter($category);
+        $conditionType = $filter->getConditionType() ?: self::CONDITION_TYPE_IN;
+        $value = $filter->getValue();
+        if ($value && in_array($conditionType, self::CONDITION_TYPES)) {
+            if ($conditionType === self::CONDITION_TYPE_EQ) {
+                $category = $this->getCategory((int) $value);
+                /** @var Collection $collection */
+                /** This filter adds ability to sort by position*/
+                $collection->addCategoryFilter($category);
+            } elseif (!$collection->getFlag('search_resut_applied')) {
+                /** Prevent filtering duplication as the filter should be already applied to the search result */
+                $values = is_array($value) ? $value : explode(',', (string) $value);
+                $categoryIds = [];
+                foreach ($values as $value) {
+                    $category = $this->getCategory((int) $value);
+                    $children = [];
+                    $childrenStr = $category->getIsAnchor() ? $category->getChildren(true) : '';
+                    if ($childrenStr) {
+                        $children = explode(',',  $childrenStr);
+                    }
+                    array_push($categoryIds, $value, ...$children);
+                }
+                /** @var Collection $collection */
+                $collection->addCategoriesFilter([$conditionType => array_map('intval', $categoryIds)]);
+            }
         }

-        $categoryProductIds = array_unique(array_merge([], ...$categoryProducts));
-        $collection->addIdFilter($categoryProductIds);
         return true;
     }
+
+    /**
+     * Retrieve the category model by ID
+     *
+     * @param int $id
+     * @return \Magento\Catalog\Model\Category
+     */
+    private function getCategory(int $id): \Magento\Catalog\Model\Category
+    {
+        /** @var \Magento\Catalog\Model\Category $category */
+        $category = $this->categoryFactory->create();
+        $this->categoryResourceModel->load($category, $id);
+        return $category;
+    }
 }
