1

MAGENTO v2.2.6

To better illustrate my question here's an example. When using the ordinary collection I can limit the attributes/fields returned like so:

NOTE: I wouldn't normally use the object manager directly, this is just an example from an ad-hoc script I created.

$productCollection = $objectManager->get(Magento\Catalog\Model\ResourceModel\Product\Collection::class);
$productCollection
    ->addAttributeToSelect('sku') /*<-- THIS IS THE FUNCTIONALITY I WANT TO MIMIC*/
    ->addFieldToFilter('manufacturer', ['eq' => 3])
    ->addFieldToFilter('price',['eq' => 234]);

foreach ($productCollection as $product){
    print_r($product->getData());
}

The above will return the following values from my particular store:

Array
(
    [entity_id] => 185
    [attribute_set_id] => 15
    [type_id] => simple
    [sku] => SKY-5001
    [has_options] => 0
    [required_options] => 0
    [created_at] => 2012-11-08 23:52:51
    [updated_at] => 2018-11-13 12:38:30
    [manufacturer] => 3
    [price] => 234.0000
)
Array
(
    [entity_id] => 186
    [attribute_set_id] => 15
    [type_id] => simple
    [sku] => SKY-5010
    [has_options] => 0
    [required_options] => 0
    [created_at] => 2012-08-11 23:52:54
    [updated_at] => 2018-11-13 12:38:30
    [manufacturer] => 3
    [price] => 234.0000
)
...

When using the getList() function located within \Magento\Catalog\Model\ProductRepository.php like in the code block below, all values from the entity are returned. I'd like to minimize the amount of data returned to only what is needed.

$searchCriteriaBuilder = $objectManager->create('Magento\Framework\Api\SearchCriteriaBuilder');
$productRepository = $objectManager->get(Magento\Catalog\Api\ProductRepositoryInterface::class);
$productSearch = $searchCriteriaBuilder->addFilter('manufacturer', 3, 'eq')->addFilter('price', 234, 'eq')->create();
$products = $productRepository->getList($productSearch)->getItems();

foreach ($products as $product){
    print_r($product->getData());
}

Here's is what's returned using the ProductRepository:

Array
(
    [entity_id] => 185
    [attribute_set_id] => 15
    [type_id] => simple
    [sku] => SKY-5001
    [has_options] => 0
    [required_options] => 0
    [created_at] => 2012-11-08 23:52:51
    [updated_at] => 2018-11-13 12:38:30
    [status] => 1
    [visibility] => 4
    [manufacturer] => 3
    [price] => 234.0000
    [description] => The 5001 On/Off Fireplace Remote Control with Backlit Touch Screen
    ...
    [size_name] => 
    [parent_sku] => 
    [color_name] => 
    [shape_name] => 
    [material_name] => 
    [inchoo_meta_robots] => 
    [mpn] => SKY-5001
    [banner_filename] => 
    [banner_category_url] => 
    [shipping_standard] => Order by 1 PM CST for Same Day Shipping
    [google_name] => 
    [remote_function_filter] => 6450
    [major_category] => Fireplace Remotes
    [sub_category1] => On/Off
    [amasty_preorder_note] => 
    [amasty_preorder_cart_label] => 
    [is_recurring] => 0
    [tax_class_id] => 2
    [fuel_type] => 
...

I've looked through the code base to no avail. Is there a way to select only specific attributes when using the Repository's getList()? I know using service contracts are the best practice, and I want to make sure I follow best practices to make upgrades and such less of a headache in the future, but I don't want to have to return every attribute or field value when getting a collection.

0

So after looking into this issue, it seems that there isn't currently (as of Magento v2.2.6) function that you can use to mimic the functionality of addAttributeToSelect. It looks like like most realistic option would be to create a custom function based on getList() and add in your own attributes that you'd like to select manually. Looking at the getList() function in vendor/magento/module-catalog/Model/ProductRepository.php

    public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCriteria)
    {
        /** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $collection */
        $collection = $this->collectionFactory->create();
        $this->extensionAttributesJoinProcessor->process($collection);

        $collection->addAttributeToSelect('*'); /*YOU'D WANT TO SELECT THE SPECIFIC ATTRIBUTES HERE*/
        $collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner');
        $collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');

        $this->collectionProcessor->process($searchCriteria, $collection);

        $collection->load();

        $collection->addCategoryIds();
        $searchResult = $this->searchResultsFactory->create();
        $searchResult->setSearchCriteria($searchCriteria);
        $searchResult->setItems($collection->getItems());
        $searchResult->setTotalCount($collection->getSize());

        foreach ($collection->getItems() as $product) {
            $this->cacheProduct(
                $this->getCacheKey(
                    [
                        false,
                        $product->hasData(\Magento\Catalog\Model\Product::STORE_ID) ? $product->getStoreId() : null
                    ]
                ),
                $product
            );
        }

        return $searchResult;
    }

So if you really want to use the Product Repository you could extend from this class and add in your own additional custom getList() function (DON'T OVERWRITE THE getList() FUNCTION ITSELF) like getListSku() in my case and update the line $collection->addAttributeToSelect('*') to $collection->addAttributeToSelect('sku').

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.