AST 19 - Nittoli - Analisi e ottimizzazione delle SERP
Hibernatesearch
1. Java Users Group Sardegna e JBoss Users group Roma
Cagliari 29 Maggio 2010
HIBERNATE SEARCH
“Gooooglizzare” efficacemente
il domain model
Sanne Grinovero
Team Hibernate per Sourcesense
3. Search engine: obiettivi
● Chi cerca non sa cosa sta cercando:
● non è in grado di inserire l'ID dell'oggetto che
desidera recuperare
● non conosce il contenuto esatto del documento
● Interfaccia tipica:
● Form complesse con molti campi
● Testo libero!
5. Specifiche “probabili”
● Campo unico
● Nome autore e/o nome prodotto
● Nome e cognome dell'autore, nomi composti
● Innanzitutto i match principali
● prodotti che corrispondono sia per nome che per
nome autore devono venire per primi
● Nomi completi di prodotto prima di nomi parziali
– “portatile mac” > “portatile”
6. SQL è il martello:
String nomeAutore = “Fabrizio De André”
String nomeProdotto = “Nuvole barocche”
List<Prodotti> list = s.createQuery( “ ...? “ );
7. SQL è il martello:
String nomeAutore = “Fabrizio De André”
String nomeProdotto = “Nuvole barocche”
List<Prodotti> list = s.createQuery( “ ...? “ );
String nomeAutore = “DeAndré Fabrizio”
String nomeProdotto = “Nuvole barocche”
List<Prodotti> list = s.createQuery( “ ...? “ );
8. SQL è il martello:
String nomeAutore = “Fabrizio De André”
String nomeProdotto = “Nuvole barocche”
List<Prodotti> list = s.createQuery( “ ...? “ );
String nomeAutore = “DeAndré Fabrizio”
String nomeProdotto = “Nuvole barocche”
List<Prodotti> list = s.createQuery( “ ...? “ );
String query = “F. de André nuvole barocche”
List<Prodotti> list = s.createQuery( “ ...???? “ );
9. E se poi “precisano” le specifiche?
● Similitudine:
● ʻhybernatʼ
● Prossimità e sinonimi:
● 'JPA' o 'Java Persistence API'
● Rilevanza:
● Più parole simili, o “più simili”
● Un termine nel titolo “vale” di più?
11. Come sarebbe Google se vi
restituisse i siti in ordine alfabetico?
“hibernate”
About 8,320,000 results (0.20 seconds)
12. Lucene
● Progetto open source Apache™,
● nella “top 10” dei più scaricati.
● Community molto attiva.
● Un'implementazione di indice invertito all'avanguaria,
costantemente aggiornato allo stato dell'arte del
settore.
● Principalmente in Java ma portato in vari altri linguaggi.
● Si trovano innumerevoli estensioni open source, ad
esempio per il supporto ottimale di tutte le lingue
occidentali.
13. Lucene
● Similitudine tra termini e documenti
● Sinonimi
● Stemming
● Stopwords
● TermVectors
● MoreLikeThis
● Faceted Search
● Velocità e scalabilità orizzontale
● ... e naturalmente ricerche full-text.
14. Similitudine
Cagliari ⁓ càliari
Cagliari ⁓ cag agl gli lia ari
Cagliari ⁓ CGRI
● N-Grams (distanza di editing)
● Fonetico (Soundex™)
● Altro... definibile secondo necessità
15. Lucene: Sinonimi (o quasi)
giornale ⁓ periodico ⁓
quotidiano
● Applicabile a “index time”
● a “query time”
● Necessita di un vocabolario
● Integrabile con vari vocabolari (WordNet)
16. Lucene: Stemming
parliamone ⁓ parlo
Velocemente ⁓ velocità
Le grammatiche di stemming sono disponibili
per un'ampia scelta di lingue, spesso free.
17. Lucene: Stopwords
● Rimuovono “rumore di fondo” e termini di
disturbo dall'indice: una ricerca per “non e
queste al per da” non da indizi su cosa l'utente
stia cercando.
18. Può sembrare facile
● La struttura di un indice è profondamente
diversa da un modello relazionale.
● L'indice e il database devono rimanere in
coerenza, immediata o eventuale.
● Incoerenza: di quale vi fidate?
● Cosa restituiscono le query?
22. Come integrare Hibernate Search
● Aggiungere hibernate-search al classpath e dipendenze
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernatesearch</artifactId>
<version>3.2.0.Final</version>
</dependency>
● Il resto è opzionale:
● Dove mettere l'indice
● Estensioni
● Parametri per le performance
● Mapping più sofisticati
● Clustering
23. Come usare Hibernate Search
@Entity
public class Essay {
@Id
public Long getId() { return id; }
public String getSummary() { return summary; }
@Lob
public String getText() { return text; }
@ManyToOne
public Author getAuthor() { return author; }
...
24. Come usare Hibernate Search
@Entity @Indexed
public class Essay {
@Id
public Long getId() { return id; }
public String getSummary() { return summary; }
@Lob
public String getText() { return text; }
@ManyToOne
public Author getAuthor() { return author; }
...
25. Come usare Hibernate Search
@Entity @Indexed
public class Essay {
@Id
public Long getId() { return id; }
@Field
public String getSummary() { return summary; }
@Lob
public String getText() { return text; }
@ManyToOne
public Author getAuthor() { return author; }
...
26. Come usare Hibernate Search
@Entity @Indexed
public class Essay {
@Id
public Long getId() { return id; }
@Field
public String getSummary() { return summary; }
@Lob @Field @Boost(0.8)
public String getText() { return text; }
@ManyToOne
public Author getAuthor() { return author; }
...
27. Come usare Hibernate Search
@Entity @Indexed
public class Essay {
@Id
public Long getId() { return id; }
@Field
public String getSummary() { return summary; }
@Lob @Field @Boost(0.8)
public String getText() { return text; }
@ManyToOne @IndexedEmbedded
public Author getAuthor() { return author; }
...
28. Altro esempio
@Entity @Entity
public class Author { public class Book {
@Id @GeneratedValue private Integer id;
private Integer id; private String title;
private String name; }
@OneToMany
private Set<Book> books;
}
29. Struttura dell'indice
@Entity @Indexed @Entity
public class Author { public class Book {
@Id @GeneratedValue private Integer id;
private Integer id; @Field(store=Store.YES)
@Field(store=Store.YES) private String title;
private String name; }
@OneToMany
@IndexedEmbedded
private Set<Book> books;
}