Nella documentazione ufficiale:
https://devdocs.magento.com/guides/v2.3/extension-dev-guide/indexing.html
c'è lo stement:
`Allows tracking database changes for a certain entity (product, category and so on) and running change handler.
Emulates the materialized view technology for MySQL using triggers and separate materialization process (provides executing PHP code instead of SQL queries, which allows materializing multiple queries).`
MView sta per Materialized View, che è un'istantanea del database in un determinato momento.
https://en.wikipedia.org/wiki/Materialized_view
Perché dovremmo duplicare le tabelle. Gli indicizzatori sono costosi da eseguire, soprattutto quando c'è traffico sulle pagine delle categorie, i clienti effettuano ordini e gli amministratori salvano i prodotti. Al salvataggio del prodotto la cache viene invalidata (fuori tema). Nel caso dell'indicizzatore di titoli, prima di terminare l'esecuzione, invia gli ID entità interessati come tag della cache da pulire (tipo di cache a pagina intera). Nelle categorie Magento 2.0 vengono inviati gli ID dei prodotti acquistati. In Magento 2.1 vengono inviati gli ID prodotto.
Esistono 2 tabelle MySQL che mantengono i codici e gli stati dell'indicizzatore:
indexer_state
mview_state
mview_state
funziona con Update by Schedule
in Ammin.> Sistema> Gestione indicizzatore
Update by Schedule
fa eseguire gli indicizzatori in cron.
Ci sono 3 voci in Magento_Indexer/etc/contab.xml
:
<group id="index">
<job name="indexer_reindex_all_invalid" instance="Magento\Indexer\Cron\ReindexAllInvalid" method="execute">
<schedule>* * * * *</schedule>
</job>
<job name="indexer_update_all_views" instance="Magento\Indexer\Cron\UpdateMview" method="execute">
<schedule>* * * * *</schedule>
</job>
<job name="indexer_clean_all_changelogs" instance="Magento\Indexer\Cron\ClearChangelog" method="execute">
<schedule>0 * * * *</schedule>
</job>
</group>
indexer_reindex_all_invalid
viene eseguito indexer_state
. C'è ancora la necessità di eseguire indicizzatori "normali" in cron
indexer_update_all_views
viene eseguito mview_state
indexer_clean_all_changelogs
- cancella i log delle modifiche utilizzati da mview_state
Si noti che le attività di gruppo cron indicizzatore eseguiti in un processo di php separata, come dichiarato in etc/contab_groups.xml
:
<use_separate_process>1</use_separate_process>
.
Le tabelle dei log delle modifiche sono:
[indexer name]_cl
(suffisso con _cl
). es cataloginventory_stock_cl
. Se gli indicizzatori sono impostati su Update by Schedule
e salvano un prodotto in admin, vedrai il entity_id
prodotto in quella tabella. È un grande cerchio, sto pensando di effettuare un ordine o creare una spedizione aggiungerà qui anche una voce.
Qualcuno ha fornito un esempio in devdoc ufficiale su come creare nuove viste materializzate e quali sono i metodi di interfaccia richiesti (ignorare la dichiarazione di cui sopra sugli ordini nel seguente snippet):
<?php
<VendorName>\Merchandizing\Model\Indexer;
class Popular implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
{
public function executeFull(); //Should take into account all placed orders in the system
public function executeList($ids); //Works with a set of placed orders (mass actions and so on)
public function executeRow($id); //Works in runtime for a single order using plugins
public function execute($ids); //Used by mview, allows you to process multiple placed orders in the "Update on schedule" mode
}
Ciò avrà senso:
//public function execute($ids); Used by mview, allows you to process multiple **entities** in the "Update on schedule" mode
}
dove $ids
parametro ha gli ID entità dalle *_cl
tabelle.
Qual è il collegamento tra invalidazione della cache e indicizzatori. Le pagine delle categorie sono ora memorizzate nella cache a tutta pagina (cache integrata per pagina intera o tramite Varnish).
C'è \Magento\Indexer\Model\Processor\InvalidateCache::afterUpdateMview
:
/**
* Update indexer views
*
* @param \Magento\Indexer\Model\Processor $subject
* @return void
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
public function afterUpdateMview(\Magento\Indexer\Model\Processor $subject)
{
if ($this->moduleManager->isEnabled('Magento_PageCache')) {
$this->eventManager->dispatch('clean_cache_after_reindex', ['object' => $this->context]);
}
}
Torna a Magento\Indexer\Cron\UpdateMview::execute()
:
/**
* Regenerate indexes for all invalid indexers
*
* @return void
*/
public function execute()
{
$this->processor->updateMview();
}
Magento\Indexer\Model\Processor::updateMview()
:
/**
* Update indexer views
*
* @return void
*/
public function updateMview()
{
$this->mviewProcessor->update('indexer');
}
In app/etc/di.xml
c'è:
<preference for="Magento\Framework\Mview\ProcessorInterface" type="Magento\Framework\Mview\Processor" />
/**
* Materialize all views by group (all views if empty)
*
* @param string $group
* @return void
*/
public function update($group = '')
{
foreach ($this->getViewsByGroup($group) as $view) {
$view->update();
}
}
Magento\Framework\Mview\ViewInterface
/**
* Materialize view by IDs in changelog
*
* @return void
* @throws \Exception
*/
public function update();
app/etc/di.xml
<preference for="Magento\Framework\Mview\ViewInterface" type="Magento\Framework\Mview\View" />
In Magento\Framework\Mview\View::update()
c'è:
$action = $this->actionFactory->get($this->getActionClass());
$this->getState()->setStatus(View\StateInterface::STATUS_WORKING)->save();
..
$action->execute($ids);
..
Se cerchi nella vendor/
directory Magento\Framework\Mview\ActionInterface
troverai ad esempio questo:
In \Magento\CatalogInventory\Model\Indexer
:
class Stock implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface
In questa classe c'è:
/**
* Execute materialization on ids entities
*
* @param int[] $ids
*
* @return void
*/
public function execute($ids)
{
$this->_productStockIndexerRows->execute($ids);
}
E sembra che risale al metodo 'execute' della classe 'normale' di indicizzatori che viene usato da MView.
Informazioni sulla pulizia della cache dopo l'indicizzatore di titoli. Quando viene effettuato un ordine al momento del pagamento, le quantità vengono sottratte utilizzando questo osservatore:\Magento\CatalogInventory\Observer\SubtractQuoteInventoryObserver
$itemsForReindex = $this->stockManagement->registerProductsSale(
$items,
$quote->getStore()->getWebsiteId()
);
Inoltre, un altro osservatore attiva l'indicizzatore (ma non direttamente su Mview / Indexer per pianificazione):
\Magento\CatalogInventory\Observer\ReindexQuoteInventoryObserver
if ($productIds) {
$this->stockIndexerProcessor->reindexList($productIds);
}
Nel caso Mview, quando vengono sottratte le nuove quantità SubtractQuoteInventoryObserver
, il trigger MySQL (creato per Mview) inserirà una riga cataloginventory_stock_cl
, indicando che è necessario eseguire un reindex (stock e testo completo) per gli ID prodotto acquistati. Esistono molti trigger MySQL creati per Mview. Guardali tutti con SHOW TRIGGERS;
.
Quando un prodotto è esaurito dopo il checkout vedrai 2 righe inserite in quella tabella (Magento salva 2 volte lo stock in questi 2 osservatori).
Quando cron esegue l'indicizzatore di titoli in modalità Mview, gli ID prodotto interessati (in M2.1) o gli ID categorie (in M2.0) vengono inviati alla cache pulita come tag cache. Per cache intendo tipo di cache a pagina intera. Esempio: catalog_product_99
o altro formato di tag cache in base alla versione di Magento. Lo stesso quando Mview non è abilitato.
\Magento\CatalogInventory\Model\Indexer\Stock\AbstractAction::_reindexRows
...
$this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]);
E Magento_PageCache ha un osservatore \Magento\PageCache\Observer\FlushCacheByTags
che pulirà il tipo di cache della pagina intera con i tag. Lo fa per la cache a pagina intera integrata. Il codice relativo alla vernice è in \Magento\CacheInvalidate\Observer\InvalidateVarnishObserver
.
Esiste un'estensione gratuita che negherà la pulizia della cache sui prodotti ancora disponibili dopo il checkout del cliente:
https://github.com/daniel-ifrim/innovo-cache-improve
Pulizia della cache solo su prodotti esauriti dopo il checkout è stato introdotto in Magento 2.2.x predefinito. Vedere \Magento\CatalogInventory\Model\Indexer\Stock\CacheCleaner
.
Sto pensando che l'esecuzione cron per indicizzatore Admin > Stores > Configuration > Advanced > System > Cron configuration options for group: index
dovrebbe essere impostata su molto più di 1 minuto.
Mview
fa riferimento a viste materializzate , che sono le tabelle degli indici.