SlideShare ist ein Scribd-Unternehmen logo
1 von 41
Downloaden Sie, um offline zu lesen
Chi sono?
Magento e TYPO3 developer in
Di cosa vi parlerò
- L’importanza della ricerca nell’e-commerce
- Cosa offre Magento
- Apache Solr
- Prestazioni
- Qualcosa in più
Ricerca
Perchè è importante
“L’80% di chi acquista
usa la ricerca per trovare
quello che vuole”
“Chi trova un prodotto
attraverso la ricerca interna
compra il doppio delle
volte”
“L’utente non ha sempre
voglia e pazienza di navigare il
catalogo per trovare quello
che vuole”
Suggerimenti
Rich auto-complete search
box
Aumenta le vendite fino a
4 volte
Jakob Nielsen, UseIt.com
Rilevanza dei risultati
“I migliori della classe, per
quanto riguarda la rilevanza
della ricerca, riescono a
fornire il prodotto cercato tra i
primi 10 solo nel 67% dei
casi”
La ricerca è un aspetto complesso che deve essere
adattato al tipo di dominio e al gruppo di utenti.
Aberdeen Group study
Abituati bene
Cosa offre Magento EE
Like
Fulltext serach
Like + Fulltext
- Non perde risultati
- Problemi di prestazioni
- Tende a restituire più di quello che serve
- Molto veloce anche su database grandi
- Risultati spesso poco rilevanti
- Poca personalizzazione (score e token)
- Migliora la rilevanza della ricerca
- Problemi di prestazioni
Mysql Fulltext
2 Modalità
Natural Language Boolean Mode
- Score basato su TF-IDF
(“term frequency / inverse document frequency”)
- MATCH (+keyword1, -keyword2)
- Score basato su numero di match
- Pesi diversi alle parole
- No customizzazioni sul metodo che usa per spezzare in parole - Tokenize
- Numero minimo di caratteri 4 (impostazione modificabile a livello global)
- Elenco di stopwords (impostazione modificabile a livello global)
- Le parole presenti nel 50% dei documenti vengono trattate come stopwords
Caratteristiche comuni
Problemi Fulltext (1/3)
Risultato atteso:
http://dev.mysql.com/doc/refman/5.7/en//fulltext-stopwords.html
Problemi Fulltext
Lunghezza minima della parola 4 caratteri e lista di parole ignorate: “Seven bag”
Query: “school”
Calcolo della rilevanza disatteso, vorrei
che il primo risultato fosse l’oggetto che
ha la Keyword nel nome.
Problemi Fulltext (2/3)
Rilevanza risultati
Problemi Fulltext (3/3)
Query: “jeens”
Se l’utente sbaglia non
ottiene nessun risultato
L’importanza del
Did you mean...
Spellcheck
Apache Solr
cos’è
High performance search engine server (basato su )
Open Source - 100% Java
caratteristiche
- Funzionalità avanzate di ricerca fulltext
- Flessibile e configurabile via XML
- Estendibile attraverso plug-in
- REST-like APIs
- Eseguito esternamente alla web-app in un Java servlet container (Tomcat, Jetty …)
- Ottimizzato per alti volumi di traffico e predisposto per scalare (replication e sharding)
- Indicizza documenti come insiemi di attributi (chiave valore)
- Parser di documenti di formati diversi (es. word, PDF, ...)
Attuali versioni stabili: 3.6.2 - 4.8.1
Funzionalità di ricerca avanzata
- Stemming Es. "pescare", "pescato", "pescatore" si riferisco a "pesce"
- Fuzzy search (es. shirt = sirt)
- Score dei risultati basati su
(VSM, TF, IDF, doc/query Boost, funzioni custom es. log(sum(popularity,1)))
- Schemaless
- Faccette (Layer navigation)
- Content elevation (risultati sponsorizzati)
- Did you mean?
- Stopwords e Synonyms (divisi per lingua)
- Recommendations (More Like This)
- Geographical search
Configurabile da XML
- ${solr.solr.home}/solr.xml
- ${istanceDir}/conf/solrconfig.xml
- ${istanceDir}/conf/schema.xml
(configurazioni: cache, ricerca, index …)
(definisce la struttura dei documenti che indicizza)
<fieldType name="text_en"
class="solr.TextField" ..>
<analyzer type="index">
<tokenizer />
<charFilter />
<filter />
</analyzer>
<analyzer ..
</fieldType>
<!-- System required fields. -->
<field name="id" type="string" indexed="true" required="true" stored="true"/>
<field name="in_stock" type="boolean" indexed="true" required="true"/>
<dynamicField name="*_def" type="textgen" indexed="true"/>
<dynamicField name="*_en" type="text_en" indexed="true"/>
<dynamicField name="*_fr" type="text_fr" indexed="true"/>
<dynamicField name="*_de" type="text_de" indexed="true"/>
Esempio di Schema
Solr + Magento EE
- Codice EE per l’integrazione + pre-configurazione per Solr 3.6.2
- Sostituisce la ricerca standard con fallback a Mysql nel caso Solr non risponda
- Sistema di indexing integrato
- Ritorna l’elenco degli ID
Solr + Magento EE
- Suggerimenti e autocorrezioni
- Calolo della rilevanza in base
al peso degli attributi
- Stopwords multi-lingua
- Faccette (Layer navigation)
- Ricerca con caratteri speciali
spider man | spiderman = > spider-man
- Migliori performance
Con elevato traffico, Solr evita i frequenti updates
della tabella MySQLcatalogsearch_fulltext e mitiga il
problema dei lock del db.
- Maggiore controllo e personalizzazione
- Scalabile
Cosa Manca?
- Auto-completamento o Rich Auto-Complete Search Box
- More Like this
- Indicizzare contenuti correlati ai prodotti (blog aziendale + Manuali in PDF)
- Regole custom per calcolo rilevanza (più venduti ecc.)
Prestazioni
Analisi sui dati 7.4 million Posts = 8.18 GB
Like
index 0
index size 0
query 49k-399k ms
(%% - rexExp)
Fulltext (MyISAM)
index 31m18s
index size 2382MiB
query 16-200ms
(boolean - natural)
Fulltext (InnoDB)
index 25m27s
index size ?
query 350-740ms
Apache Solr
index 14m28
index size 2766MiB
query 79ms
Full Text Search Throwdown Bill Karwin, Percona Inc.
Ricerca del 2012
2 aspetti da considerare in Magento
Test su strada
Dataset
Ricerca per keyword Navigazione catalogo
Ricerca per keyword
Maximizing Performance and Scalability with Magento Enterprise Edition
http://www.magentocommerce.com/whitepaper/
Nostri test interni
Ricerca Concorrenza Tempo di risposta medio
Like 1 2.09
Like 5 3
Like 10 5
Like 20 13.65 sec
Fullsearch 1 1.4
Fullsearch 5 1.96
Fullsearch 10 3.04
Fullsearch 20 5.14
Solr 1 1.45
Solr 5 2.20
Solr 10 3.06
Solr 20 5.4
50K prodotti
Quad core
4GB di ram
Navigazione faccette
Maximizing Performance and Scalability with Magento Enterprise Edition
http://www.magentocommerce.com/whitepaper/
Magento CE
Community ?
- Compatibile con Solr 4.x
- Autocompletamento
- Ricerca per keyword
- Indexing integrato
- Configurazione Solr base
Istant Search
Istant Search
(Da auto-complete a rich auto-complete)
Quello che fa già
l’estensione
- Schema.xml
- Indicizzatore
- QueryBuilder
- Frontend Block
Dove intervenire
app/code/community/JeroenVermeulen/
Solarium/Model/Engine.php
app/code/community/JeroenVermeulen/
Solarium/Model/Engine.php
app/code/community/JeroenVermeulen/
Solarium/Block/Catalogsearch/
Autocomplete.php
${istanceDir}/conf/schema.xml
<schema name="magento_fulltext" version="100">
<types>
...
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
</types>
<fields>
<field name="id" type="int" indexed="true" stored="true" required="true"/>
<field name="product_id" type="string" indexed="true" stored="true" required="true"
/>
<field name="store_id" type="int" indexed="true" stored="true" required="true"/>
<!-- Magento Product Fulltext -->
<field name="text" type="text_general" indexed="true" stored="true"/>
<field name="url" type="string" indexed="false" stored="true"/>
<field name="image" type="string" indexed="false" stored="true"/>
<field name="name" type="text_general" indexed="true" stored="true"/>
<field name="_version_" type="long" indexed="true" stored="true"/>
</fields>
<uniqueKey>id</uniqueKey>
<solrQueryParser defaultOperator="AND"/>
</schema>
- Schema.xml
- Indicizzatore
- QueryBuilder
- Frontend Block
Dove intervenire
app/code/community/JeroenVermeulen/
Solarium/Model/Engine.php
app/code/community/JeroenVermeulen/
Solarium/Model/Engine.php
app/code/community/JeroenVermeulen/
Solarium/Block/Catalogsearch/
Autocomplete.php
${istanceDir}/conf/schema.xml
public function rebuildIndex( $storeId = null, $productIds = null ) {
...
while ( $product = $products->fetch() ) {
$productModel = Mage::getModel('catalog/product')
->setStoreId($storeId)
->load($product[ 'product_id' ]);
$data = array( 'id' => intval( $product[ 'fulltext_id' ] ),
…
'name' => $productModel->getName()
);
$buffer->createDocument( $data );
}
$solariumResult = $buffer->flush();
…
}
<doc>
<field name="id">123</field>
<field name="product_id">166</field>
<field name="store_id">1</field>
<field name="text">Fulltext index | </field>
<field name="url">url</field>
<field name="image">url_image</field>
<field name="name">Nome prodotto</field>
</doc>
- Schema.xml
- Indicizzatore
- QueryBuilder
- Frontend Block
Dove intervenire
app/code/community/JeroenVermeulen/
Solarium/Model/Engine.php
app/code/community/JeroenVermeulen/
Solarium/Model/Engine.php
app/code/community/JeroenVermeulen/
Solarium/Block/Catalogsearch/
Autocomplete.php
${istanceDir}/conf/schema.xml
…
$query = $this->_client->createSelect();
$query->addParam( 'df', 'text' );
$query->setQuery( $this->_filterString( $queryString ). '*' );
$query->setRows( $this->getConf( 'results/max' ) );
$query->setFields( array( 'product_id', 'score', 'name', 'image', 'url') );
$dismax = $query->getEDisMax();
$dismax->setQueryFields('name^2 product_id^1.5 text');
$solrResultSet = $this->_client->select( $query );
…
{
"response":{
"numFound":15,
"start":0,
"maxScore":1.0,
"docs":[
{
"product_id":"164",
"name":"Gaming Computer",
"score":1.0
},
{
"product_id":"162",
"name":"Microsoft Wireles",
"score":1.0
},
…
]
}
Result
http://localhost:8983/solr/select/?
spellcheck=true&sort=score+des&spellcheck.q=micr*&json.
nl=flat&wt=json&rows=100&omitHeader=true&df=text&fl=product_id,score,text,
name&start=0
&q=micr*&timeAllowed=5&fq=store_id:1&spellcheck.alternativeTermCount=1
Query
- Schema.xml
- Indicizzatore
- QueryBuilder
- Frontend Block
Dove intervenire
app/code/community/JeroenVermeulen/
Solarium/Model/Engine.php
app/code/community/JeroenVermeulen/
Solarium/Model/Engine.php
app/code/community/JeroenVermeulen/
Solarium/Block/Catalogsearch/
Autocomplete.php
${istanceDir}/conf/schema.xml
class JeroenVermeulen_Solarium_Block_Catalogsearch_Autocomplete extends
Mage_CatalogSearch_Block_Autocomplete {
…
public function getSuggestProduct()
{
if ( ! $this->_suggestProduct ) {
$query = $this->helper('catalogsearch')->getQueryText();
$query = $query . '*';
$counter = 0;
$data = array();
$storeId = Mage::app()->getStore()->getId();
$engine = Mage::getSingleton('jeroenvermeulen_solarium/engine');
$products = $engine->queryAutosuggest( $storeId, $query, 1 );
foreach ( $products as $value) {
$_datap = array(
'id' => $value['product_id'],
'row_class' => ( ++$counter ) % 2 ? 'odd' : 'even',
'text' => $value['name'],
…
);
$datap[] = $_datap;
}
$this->_suggestProduct = $datap;
}
return $this->_suggestProduct;
}
…
}
Risultato
(Da Auto-complete a
Rich auto-complete)
Con Varnish la ricerca diventa istantanea
Modifichiamo la rilevanza
...&defType=edismax&qf=name^2.0+text
https://www.youtube.com/watch?v=RDb8WLzgzEg
Riepilogo
+ Rilevanza nella ricerca
+
Riepilogo
+ Rilevanza nella ricerca
+ Adattabile al dominio
+
Riepilogo
+ Rilevanza nella ricerca
+ Adattabile al dominio
+ Pronto per scalare+
Riepilogo
+ Rilevanza nella ricerca
+ Adattabile al dominio
+ Pronto per scalare
+ Migliori prestazioni
+
Riepilogo
+ Rilevanza nella ricerca
+ Adattabile al dominio
+ Pronto per scalare
+ Migliori prestazioni
+
= Migliore esperienza utente
Riepilogo
+
= maggiori conversioni
?Domande
Luca Peressini
Mail: luca.peressini@webformat.com
twitter: @PeressiniLuca
linkedin: http://it.linkedin.com/pub/luca-peressini/56/182/128

Weitere ähnliche Inhalte

Ähnlich wie Luca Peressini: Integrare Apache Solr in Magento per migliorare la ricerca

Sviluppo web con Ruby on Rails
Sviluppo web con Ruby on RailsSviluppo web con Ruby on Rails
Sviluppo web con Ruby on Railsjekil
 
Creare API pubbliche, come evitare gli errori comuni
 Creare API pubbliche, come evitare gli errori comuni Creare API pubbliche, come evitare gli errori comuni
Creare API pubbliche, come evitare gli errori comuniAndrea Dottor
 
Nicola Della Marina: Magento Frontend next level
Nicola Della Marina: Magento Frontend next levelNicola Della Marina: Magento Frontend next level
Nicola Della Marina: Magento Frontend next levelMeet Magento Italy
 
MongoDB Scala Roma SpringFramework Meeting2009
MongoDB Scala Roma SpringFramework Meeting2009MongoDB Scala Roma SpringFramework Meeting2009
MongoDB Scala Roma SpringFramework Meeting2009Massimiliano Dessì
 
MongoDb and Scala SpringFramework Meeting
MongoDb and Scala SpringFramework MeetingMongoDb and Scala SpringFramework Meeting
MongoDb and Scala SpringFramework Meetingguest67beeb9
 
Accelera lo sviluppo con il web framework! Componenti a supporto dello svilup...
Accelera lo sviluppo con il web framework! Componenti a supporto dello svilup...Accelera lo sviluppo con il web framework! Componenti a supporto dello svilup...
Accelera lo sviluppo con il web framework! Componenti a supporto dello svilup...Tsuneo Kurihara
 
CakePhp Linux Day Torino '09
CakePhp Linux Day Torino '09CakePhp Linux Day Torino '09
CakePhp Linux Day Torino '09Francesco Ronchi
 
Seo e Web Marketing - 1 | WebMaster & WebDesigner
Seo e Web Marketing - 1 | WebMaster & WebDesignerSeo e Web Marketing - 1 | WebMaster & WebDesigner
Seo e Web Marketing - 1 | WebMaster & WebDesignerMatteo Magni
 
Corso eBIZ -Modulo 01 - introduzione (CW513-004)
Corso eBIZ -Modulo  01 - introduzione (CW513-004)Corso eBIZ -Modulo  01 - introduzione (CW513-004)
Corso eBIZ -Modulo 01 - introduzione (CW513-004)ENEA DTE-SEN-CROSS
 
Drupal 7 : theming avanzato
Drupal 7 : theming avanzatoDrupal 7 : theming avanzato
Drupal 7 : theming avanzatoTwinbit
 
Asp.net web form 4.5 - what's new!!
Asp.net web form 4.5 - what's new!!Asp.net web form 4.5 - what's new!!
Asp.net web form 4.5 - what's new!!Massimo Bonanni
 
Elasticsearch a quick introduction
Elasticsearch a quick introductionElasticsearch a quick introduction
Elasticsearch a quick introductionFederico Panini
 
RDFa 1.1 - Seminario Web Semantico 2015
 RDFa 1.1 - Seminario Web Semantico 2015 RDFa 1.1 - Seminario Web Semantico 2015
RDFa 1.1 - Seminario Web Semantico 2015Giuseppe Luciano
 
Design Patterns - enterprise patterns (part I)
Design Patterns - enterprise patterns (part I)Design Patterns - enterprise patterns (part I)
Design Patterns - enterprise patterns (part I)Fabio Armani
 

Ähnlich wie Luca Peressini: Integrare Apache Solr in Magento per migliorare la ricerca (20)

Drupal + Apache SOLR
Drupal + Apache SOLRDrupal + Apache SOLR
Drupal + Apache SOLR
 
Sviluppo web con Ruby on Rails
Sviluppo web con Ruby on RailsSviluppo web con Ruby on Rails
Sviluppo web con Ruby on Rails
 
Java lezione 17
Java lezione 17Java lezione 17
Java lezione 17
 
Repository pattern
Repository patternRepository pattern
Repository pattern
 
Creare API pubbliche, come evitare gli errori comuni
 Creare API pubbliche, come evitare gli errori comuni Creare API pubbliche, come evitare gli errori comuni
Creare API pubbliche, come evitare gli errori comuni
 
Powerful asp.net 4 e ie9
Powerful asp.net 4 e ie9Powerful asp.net 4 e ie9
Powerful asp.net 4 e ie9
 
Nicola Della Marina: Magento Frontend next level
Nicola Della Marina: Magento Frontend next levelNicola Della Marina: Magento Frontend next level
Nicola Della Marina: Magento Frontend next level
 
MongoDB Scala Roma SpringFramework Meeting2009
MongoDB Scala Roma SpringFramework Meeting2009MongoDB Scala Roma SpringFramework Meeting2009
MongoDB Scala Roma SpringFramework Meeting2009
 
MongoDb and Scala SpringFramework Meeting
MongoDb and Scala SpringFramework MeetingMongoDb and Scala SpringFramework Meeting
MongoDb and Scala SpringFramework Meeting
 
Many Designs Elements
Many Designs ElementsMany Designs Elements
Many Designs Elements
 
Accelera lo sviluppo con il web framework! Componenti a supporto dello svilup...
Accelera lo sviluppo con il web framework! Componenti a supporto dello svilup...Accelera lo sviluppo con il web framework! Componenti a supporto dello svilup...
Accelera lo sviluppo con il web framework! Componenti a supporto dello svilup...
 
CakePhp Linux Day Torino '09
CakePhp Linux Day Torino '09CakePhp Linux Day Torino '09
CakePhp Linux Day Torino '09
 
Seo e Web Marketing - 1 | WebMaster & WebDesigner
Seo e Web Marketing - 1 | WebMaster & WebDesignerSeo e Web Marketing - 1 | WebMaster & WebDesigner
Seo e Web Marketing - 1 | WebMaster & WebDesigner
 
Corso eBIZ -Modulo 01 - introduzione (CW513-004)
Corso eBIZ -Modulo  01 - introduzione (CW513-004)Corso eBIZ -Modulo  01 - introduzione (CW513-004)
Corso eBIZ -Modulo 01 - introduzione (CW513-004)
 
Drupal 7 : theming avanzato
Drupal 7 : theming avanzatoDrupal 7 : theming avanzato
Drupal 7 : theming avanzato
 
Asp.net web form 4.5 - what's new!!
Asp.net web form 4.5 - what's new!!Asp.net web form 4.5 - what's new!!
Asp.net web form 4.5 - what's new!!
 
Elasticsearch a quick introduction
Elasticsearch a quick introductionElasticsearch a quick introduction
Elasticsearch a quick introduction
 
Seo con drupal
Seo con drupalSeo con drupal
Seo con drupal
 
RDFa 1.1 - Seminario Web Semantico 2015
 RDFa 1.1 - Seminario Web Semantico 2015 RDFa 1.1 - Seminario Web Semantico 2015
RDFa 1.1 - Seminario Web Semantico 2015
 
Design Patterns - enterprise patterns (part I)
Design Patterns - enterprise patterns (part I)Design Patterns - enterprise patterns (part I)
Design Patterns - enterprise patterns (part I)
 

Luca Peressini: Integrare Apache Solr in Magento per migliorare la ricerca

  • 1.
  • 2. Chi sono? Magento e TYPO3 developer in
  • 3. Di cosa vi parlerò - L’importanza della ricerca nell’e-commerce - Cosa offre Magento - Apache Solr - Prestazioni - Qualcosa in più
  • 5. Perchè è importante “L’80% di chi acquista usa la ricerca per trovare quello che vuole” “Chi trova un prodotto attraverso la ricerca interna compra il doppio delle volte” “L’utente non ha sempre voglia e pazienza di navigare il catalogo per trovare quello che vuole” Suggerimenti Rich auto-complete search box Aumenta le vendite fino a 4 volte Jakob Nielsen, UseIt.com
  • 6. Rilevanza dei risultati “I migliori della classe, per quanto riguarda la rilevanza della ricerca, riescono a fornire il prodotto cercato tra i primi 10 solo nel 67% dei casi” La ricerca è un aspetto complesso che deve essere adattato al tipo di dominio e al gruppo di utenti. Aberdeen Group study Abituati bene
  • 7. Cosa offre Magento EE Like Fulltext serach Like + Fulltext - Non perde risultati - Problemi di prestazioni - Tende a restituire più di quello che serve - Molto veloce anche su database grandi - Risultati spesso poco rilevanti - Poca personalizzazione (score e token) - Migliora la rilevanza della ricerca - Problemi di prestazioni
  • 8. Mysql Fulltext 2 Modalità Natural Language Boolean Mode - Score basato su TF-IDF (“term frequency / inverse document frequency”) - MATCH (+keyword1, -keyword2) - Score basato su numero di match - Pesi diversi alle parole - No customizzazioni sul metodo che usa per spezzare in parole - Tokenize - Numero minimo di caratteri 4 (impostazione modificabile a livello global) - Elenco di stopwords (impostazione modificabile a livello global) - Le parole presenti nel 50% dei documenti vengono trattate come stopwords Caratteristiche comuni
  • 9. Problemi Fulltext (1/3) Risultato atteso: http://dev.mysql.com/doc/refman/5.7/en//fulltext-stopwords.html Problemi Fulltext Lunghezza minima della parola 4 caratteri e lista di parole ignorate: “Seven bag”
  • 10. Query: “school” Calcolo della rilevanza disatteso, vorrei che il primo risultato fosse l’oggetto che ha la Keyword nel nome. Problemi Fulltext (2/3) Rilevanza risultati
  • 11. Problemi Fulltext (3/3) Query: “jeens” Se l’utente sbaglia non ottiene nessun risultato L’importanza del Did you mean... Spellcheck
  • 13. cos’è High performance search engine server (basato su ) Open Source - 100% Java caratteristiche - Funzionalità avanzate di ricerca fulltext - Flessibile e configurabile via XML - Estendibile attraverso plug-in - REST-like APIs - Eseguito esternamente alla web-app in un Java servlet container (Tomcat, Jetty …) - Ottimizzato per alti volumi di traffico e predisposto per scalare (replication e sharding) - Indicizza documenti come insiemi di attributi (chiave valore) - Parser di documenti di formati diversi (es. word, PDF, ...) Attuali versioni stabili: 3.6.2 - 4.8.1
  • 14. Funzionalità di ricerca avanzata - Stemming Es. "pescare", "pescato", "pescatore" si riferisco a "pesce" - Fuzzy search (es. shirt = sirt) - Score dei risultati basati su (VSM, TF, IDF, doc/query Boost, funzioni custom es. log(sum(popularity,1))) - Schemaless - Faccette (Layer navigation) - Content elevation (risultati sponsorizzati) - Did you mean? - Stopwords e Synonyms (divisi per lingua) - Recommendations (More Like This) - Geographical search
  • 15. Configurabile da XML - ${solr.solr.home}/solr.xml - ${istanceDir}/conf/solrconfig.xml - ${istanceDir}/conf/schema.xml (configurazioni: cache, ricerca, index …) (definisce la struttura dei documenti che indicizza) <fieldType name="text_en" class="solr.TextField" ..> <analyzer type="index"> <tokenizer /> <charFilter /> <filter /> </analyzer> <analyzer .. </fieldType> <!-- System required fields. --> <field name="id" type="string" indexed="true" required="true" stored="true"/> <field name="in_stock" type="boolean" indexed="true" required="true"/> <dynamicField name="*_def" type="textgen" indexed="true"/> <dynamicField name="*_en" type="text_en" indexed="true"/> <dynamicField name="*_fr" type="text_fr" indexed="true"/> <dynamicField name="*_de" type="text_de" indexed="true"/> Esempio di Schema
  • 16. Solr + Magento EE - Codice EE per l’integrazione + pre-configurazione per Solr 3.6.2 - Sostituisce la ricerca standard con fallback a Mysql nel caso Solr non risponda - Sistema di indexing integrato - Ritorna l’elenco degli ID
  • 17. Solr + Magento EE - Suggerimenti e autocorrezioni - Calolo della rilevanza in base al peso degli attributi - Stopwords multi-lingua - Faccette (Layer navigation) - Ricerca con caratteri speciali spider man | spiderman = > spider-man - Migliori performance Con elevato traffico, Solr evita i frequenti updates della tabella MySQLcatalogsearch_fulltext e mitiga il problema dei lock del db. - Maggiore controllo e personalizzazione - Scalabile
  • 18. Cosa Manca? - Auto-completamento o Rich Auto-Complete Search Box - More Like this - Indicizzare contenuti correlati ai prodotti (blog aziendale + Manuali in PDF) - Regole custom per calcolo rilevanza (più venduti ecc.)
  • 20. Analisi sui dati 7.4 million Posts = 8.18 GB Like index 0 index size 0 query 49k-399k ms (%% - rexExp) Fulltext (MyISAM) index 31m18s index size 2382MiB query 16-200ms (boolean - natural) Fulltext (InnoDB) index 25m27s index size ? query 350-740ms Apache Solr index 14m28 index size 2766MiB query 79ms Full Text Search Throwdown Bill Karwin, Percona Inc. Ricerca del 2012 2 aspetti da considerare in Magento Test su strada Dataset Ricerca per keyword Navigazione catalogo
  • 21. Ricerca per keyword Maximizing Performance and Scalability with Magento Enterprise Edition http://www.magentocommerce.com/whitepaper/
  • 22. Nostri test interni Ricerca Concorrenza Tempo di risposta medio Like 1 2.09 Like 5 3 Like 10 5 Like 20 13.65 sec Fullsearch 1 1.4 Fullsearch 5 1.96 Fullsearch 10 3.04 Fullsearch 20 5.14 Solr 1 1.45 Solr 5 2.20 Solr 10 3.06 Solr 20 5.4 50K prodotti Quad core 4GB di ram
  • 23. Navigazione faccette Maximizing Performance and Scalability with Magento Enterprise Edition http://www.magentocommerce.com/whitepaper/
  • 25. Community ? - Compatibile con Solr 4.x - Autocompletamento - Ricerca per keyword - Indexing integrato - Configurazione Solr base
  • 27. Istant Search (Da auto-complete a rich auto-complete) Quello che fa già l’estensione
  • 28. - Schema.xml - Indicizzatore - QueryBuilder - Frontend Block Dove intervenire app/code/community/JeroenVermeulen/ Solarium/Model/Engine.php app/code/community/JeroenVermeulen/ Solarium/Model/Engine.php app/code/community/JeroenVermeulen/ Solarium/Block/Catalogsearch/ Autocomplete.php ${istanceDir}/conf/schema.xml <schema name="magento_fulltext" version="100"> <types> ... <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100"> <analyzer type="index"> <tokenizer class="solr.StandardTokenizerFactory"/> <filter class="solr.LowerCaseFilterFactory"/> </analyzer> <analyzer type="query"> <tokenizer class="solr.StandardTokenizerFactory"/> <filter class="solr.LowerCaseFilterFactory"/> </analyzer> </fieldType> </types> <fields> <field name="id" type="int" indexed="true" stored="true" required="true"/> <field name="product_id" type="string" indexed="true" stored="true" required="true" /> <field name="store_id" type="int" indexed="true" stored="true" required="true"/> <!-- Magento Product Fulltext --> <field name="text" type="text_general" indexed="true" stored="true"/> <field name="url" type="string" indexed="false" stored="true"/> <field name="image" type="string" indexed="false" stored="true"/> <field name="name" type="text_general" indexed="true" stored="true"/> <field name="_version_" type="long" indexed="true" stored="true"/> </fields> <uniqueKey>id</uniqueKey> <solrQueryParser defaultOperator="AND"/> </schema>
  • 29. - Schema.xml - Indicizzatore - QueryBuilder - Frontend Block Dove intervenire app/code/community/JeroenVermeulen/ Solarium/Model/Engine.php app/code/community/JeroenVermeulen/ Solarium/Model/Engine.php app/code/community/JeroenVermeulen/ Solarium/Block/Catalogsearch/ Autocomplete.php ${istanceDir}/conf/schema.xml public function rebuildIndex( $storeId = null, $productIds = null ) { ... while ( $product = $products->fetch() ) { $productModel = Mage::getModel('catalog/product') ->setStoreId($storeId) ->load($product[ 'product_id' ]); $data = array( 'id' => intval( $product[ 'fulltext_id' ] ), … 'name' => $productModel->getName() ); $buffer->createDocument( $data ); } $solariumResult = $buffer->flush(); … } <doc> <field name="id">123</field> <field name="product_id">166</field> <field name="store_id">1</field> <field name="text">Fulltext index | </field> <field name="url">url</field> <field name="image">url_image</field> <field name="name">Nome prodotto</field> </doc>
  • 30. - Schema.xml - Indicizzatore - QueryBuilder - Frontend Block Dove intervenire app/code/community/JeroenVermeulen/ Solarium/Model/Engine.php app/code/community/JeroenVermeulen/ Solarium/Model/Engine.php app/code/community/JeroenVermeulen/ Solarium/Block/Catalogsearch/ Autocomplete.php ${istanceDir}/conf/schema.xml … $query = $this->_client->createSelect(); $query->addParam( 'df', 'text' ); $query->setQuery( $this->_filterString( $queryString ). '*' ); $query->setRows( $this->getConf( 'results/max' ) ); $query->setFields( array( 'product_id', 'score', 'name', 'image', 'url') ); $dismax = $query->getEDisMax(); $dismax->setQueryFields('name^2 product_id^1.5 text'); $solrResultSet = $this->_client->select( $query ); … { "response":{ "numFound":15, "start":0, "maxScore":1.0, "docs":[ { "product_id":"164", "name":"Gaming Computer", "score":1.0 }, { "product_id":"162", "name":"Microsoft Wireles", "score":1.0 }, … ] } Result http://localhost:8983/solr/select/? spellcheck=true&sort=score+des&spellcheck.q=micr*&json. nl=flat&wt=json&rows=100&omitHeader=true&df=text&fl=product_id,score,text, name&start=0 &q=micr*&timeAllowed=5&fq=store_id:1&spellcheck.alternativeTermCount=1 Query
  • 31. - Schema.xml - Indicizzatore - QueryBuilder - Frontend Block Dove intervenire app/code/community/JeroenVermeulen/ Solarium/Model/Engine.php app/code/community/JeroenVermeulen/ Solarium/Model/Engine.php app/code/community/JeroenVermeulen/ Solarium/Block/Catalogsearch/ Autocomplete.php ${istanceDir}/conf/schema.xml class JeroenVermeulen_Solarium_Block_Catalogsearch_Autocomplete extends Mage_CatalogSearch_Block_Autocomplete { … public function getSuggestProduct() { if ( ! $this->_suggestProduct ) { $query = $this->helper('catalogsearch')->getQueryText(); $query = $query . '*'; $counter = 0; $data = array(); $storeId = Mage::app()->getStore()->getId(); $engine = Mage::getSingleton('jeroenvermeulen_solarium/engine'); $products = $engine->queryAutosuggest( $storeId, $query, 1 ); foreach ( $products as $value) { $_datap = array( 'id' => $value['product_id'], 'row_class' => ( ++$counter ) % 2 ? 'odd' : 'even', 'text' => $value['name'], … ); $datap[] = $_datap; } $this->_suggestProduct = $datap; } return $this->_suggestProduct; } … }
  • 32. Risultato (Da Auto-complete a Rich auto-complete) Con Varnish la ricerca diventa istantanea
  • 36. Riepilogo + Rilevanza nella ricerca + Adattabile al dominio +
  • 37. Riepilogo + Rilevanza nella ricerca + Adattabile al dominio + Pronto per scalare+
  • 38. Riepilogo + Rilevanza nella ricerca + Adattabile al dominio + Pronto per scalare + Migliori prestazioni +
  • 39. Riepilogo + Rilevanza nella ricerca + Adattabile al dominio + Pronto per scalare + Migliori prestazioni + = Migliore esperienza utente
  • 41. ?Domande Luca Peressini Mail: luca.peressini@webformat.com twitter: @PeressiniLuca linkedin: http://it.linkedin.com/pub/luca-peressini/56/182/128