1

Magento 1.7.

I noticed that when you update inventory quantities, a reindex of catalog_product_flat is not required.

That's useful, because I can set up a cron job to update inventory every night at 3 am. Importing the data for 20,000 items only takes about a minute. If reindex was required, it would add at least another 10 minutes.

Now, I want to also show Estimated Time of Arrival dates for out of stock items. I can import the data at the same time as the stock quantities. But if I create a regular attribute for that date, then every time I import, the index will be invalidated. Isn't that correct?

Is there any way I can create an attribute that works like stock quantity does, i.e. one that doesn't require any reindexing? I know there is a stock status index in 1.7, but it does not seem to get invalidated by just changing stock quantities (we use Manage Stock = No).

I was thinking that as a hack, I could use the "news_from_date" (which we don't use anyway) to hold that date.

UPDATE I changed the question Title to better reflect what my problem really is.

Fundamentally, I want to avoid the catalog_product_flat_1 table reindex. Why? Because it drops the table and rebuilds it, and while that is happening the frontend is non-functional. With 70,000+ items to reindex (and more coming), the downtime is at least 5 minutes.

To avoid reindexing, I suggested creating an attribute that works like stock qty, but perhaps that is too hard to do.

What about saving each product and updating its index entry? I think that with UPDATE queries, the catalog_prodct_flat_1 table would continue working, and the frontend would continue working. Is that a correct assumption?

Do individual product saving methods update the index, or do they invalidate it?

As long as Magento is only sending update queries to the flat table index, I think the frontend would remain operational. A complete reindex renders the frontend unusable for some time.

1

If you only want to update a single product attribute without running the indexer, use the following method. It will be possible to update a couple of hundred products per second that way.

First, add a new product attribute estimated_time_of_arrival.
The, in your update script:

$product->addAttributeUpdate(
    'estimated_time_of_arrival',
    $date,
    $storeId // numeric store id value, e.g. Mage::app()->getStore()->getId()
);

If it's a global scope attribute, the $storeId doesn't even matter.
If you don't care about the store ID scope, you can also use:

$product->setData('estimated_time_of_arrival', $date)
    ->getResource()
    ->saveAttribute($product, 'estimated_time_of_arrival');

Both methods are equivalent (the latter will use $product->getStoreId()if the attribute has a website or store view scope).

Of course, if you use that attribute in some way that requires indexing, you will have to reindex after the updates.

1
  • "Of course, if you use that attribute in some way that requires indexing, you will have to reindex after the updates." My site is set to use the product flat table. When I use your method, I suppose that the flat table index will be invalidated. I would like to avoid that if possible. Isn't there any method that saves the product data AND updates the flat table without invalidating the index? Jun 25 '13 at 23:05
1

Stock inventory data is saved to another cataloginventory_stock_item table rather than product eav attributes and no required Product Flat Data indexation. But it triggers Stock Status indexation. For you needs easy way is using standard product attributes. But it requires Product Flat Data index when you want display these attributes on frontend and your store uses Flat Catalog Product table (see admin->system->config->catalog settings).
Second option is using another table to store your attributes, but you should load these attributes with additional query while displaying products. It is not right approach.
You can switch off auto indexation while saving products and after update your store products you can do all index automatically. See logic:

//switch index mode to manual
$pCollection = Mage::getSingleton('index/indexer')
            ->getProcessesCollection();
foreach ($pCollection as $process) {
   $process->setMode(Mage_Index_Model_Process::MODE_MANUAL)->save();
}

//here your product updating logic
foreach($products as $product){
    $product->setSomeValue('some value')->setAnotherValue($anotherValue);
    try{
       $product->save();
    }catch(Exception $e){
       Mage::logException($e);
    }
}
//product updating ends here

//switch index mode to real time and reindex
foreach ($pCollection as $process) {
    $process->setMode(Mage_Index_Model_Process::MODE_REAL_TIME)->save();
    try{
       $process->reindexEverything();
    }catch(Exception $e){
       Mage::logException($e);
    }
}

Updated

You can use this method for updating attributes without indexation:

$productIds = array($product->getId()); // you can add several product ids to this array if their attribute-value pairs are same.
$attributes = array('estimated_time_of_arrival' => $someValue);// you can add several attribute-value pair to this array.
$storeId    = Mage::app()->getStore()->getId();
Mage::getSingleton('catalog/product_action')->updateAttributes($productIds, $attributes, $storeId);
1
  • Thanks for your answer. I've updated my question to better reflect my problem. Your first code sample updates products and then does complete reindex. That is exactly what I do NOT want. In your Update, you are avoiding reindex. But will the updated values be saved in the flat table or will I still have to reindex to get them there? I need a way to update the flat table with new values without invalidating the index. Jun 25 '13 at 23:02
0

I am facing somewhat similar issue, When i update product attribute value using cron. Those products shows "Out of stock" in front-end at category listing. But it shows in-stock in back-end.

I found the issue is with $_product->getSaleable() always return false. How can we resolve such issue?

1
  • Do you have "Manage Stock" set to yes or no? By the way, you should post this as a separate question, rather than as an answer. Aug 7 '13 at 22:15

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.