SlideShare a Scribd company logo
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
Example database
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!
Idea:
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”
SQL è il martello:

String nomeAutore = “Fabrizio De André”
String nomeProdotto = “Nuvole barocche”
List<Prodotti> list = s.createQuery( “ ...? “ );
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( “ ...? “ );
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( “ ...???? “ );
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ù?
Come sarebbe Google se vi
restituisse i siti in ordine alfabetico?
Come sarebbe Google se vi
restituisse i siti in ordine alfabetico?

“hibernate”
About 8,320,000 results (0.20 seconds)
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.
Lucene
●   Similitudine tra termini e documenti
●   Sinonimi
●   Stemming
●   Stopwords
●   TermVectors
●   MoreLikeThis
●   Faceted Search
●   Velocità e scalabilità orizzontale

●   ... e naturalmente ricerche full-text.
Similitudine


            Cagliari ⁓ càliari
      Cagliari ⁓ cag agl gli lia ari
            Cagliari ⁓ CGRI
●   N-Grams (distanza di editing)
●   Fonetico (Soundex™)
●   Altro... definibile secondo necessità
Lucene: Sinonimi (o quasi)


        giornale ⁓ periodico ⁓
              quotidiano

●   Applicabile a “index time”
●   a “query time”
●   Necessita di un vocabolario
●   Integrabile con vari vocabolari (WordNet)
Lucene: Stemming

    parliamone ⁓ parlo
  Velocemente ⁓ velocità

Le grammatiche di stemming sono disponibili
per un'ampia scelta di lingue, spesso free.
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.
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?
Differenze strutturali
 dell'informazione
Incoerenze architetturali
May 2010 - Hibernate search
Come integrare Hibernate Search
●   Aggiungere hibernate-search al classpath e dipendenze
<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate­search</artifactId>
   <version>3.2.0.Final</version>
</dependency>
●   Il resto è opzionale:
    ●   Dove mettere l'indice
    ●   Estensioni
    ●   Parametri per le performance
    ●   Mapping più sofisticati
    ●   Clustering
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; }
...
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; }
...
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; }
...
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; }
...
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; }
...
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;
}
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;
}
Codice di Query:
String[] productFields = {"summary", "author.name"};

QueryParser parser = new MultiFieldQueryParser(productFields,
   new StandardAnalyzer() );

Query luceneQuery = parser.parse(searchQuery);

FullTextEntityManager ftEm =
   Search.getFullTextEntityManager(entityManager);

FullTextQuery query =
   ftEm.createFullTextQuery(luceneQuery,Product.class );

List<Essay> items = query.setMaxResults(100).getResultList();

int totalNbrOfResults = query.getResultSize();
                                 TotalNbrOfResults= 8.320.000
                                 (0.20 seconds)
Risultati
●   Pojo gestiti!
●   Paginazione
    ●   .setMaxResults( 20 ).setFirstResult( 100 );
●   Restrizioni per tipo
    ●   .createQuery( luceneQuery, A.class, B.class, ..);
●   Projection
●   Result mapping
Demo / Tests
        org.hibernate.search.test.filter.FilterTest
org.hibernate.search.test.compression.CompressionTest
May 2010 - Hibernate search
Filtri

 @Indexed @Entity
 @FullTextFilterDefs( {
    @FullTextFilterDef(name = "disponibiliSubito", impl =      
 ProdDisponibileFilter.class, cache = 
FilterCacheModeType.NONE),
    @FullTextFilterDef(name = "security", impl = 
SecurityFilterFactory.class, cache = 
FilterCacheModeType.INSTANCE_AND_DOCIDSETRESULTS)
 })
 public class Prodotto {
    ...
Filtri
FullTextQuery ftQuery = s // s è di tipo FullTextSession
   .createFullTextQuery( query, Prodotto.class )
   .enableFullTextFilter( "vietatoMinori" )
   .enableFullTextFilter( "offerteDelGiorno" )
      .setParameter( "giorno", “20100529” )
   .enableFullTextFilter( "disponibiliSubito" )
      .setParameter( "sede", "Cagliari" );
List<Prodotto> risultati = ftQuery.list();
Analizzatori custom
@Entity @Indexed
@AnalyzerDef(name = "italianAnalyzer",tokenizer = 
@TokenizerDef(factory=StandardTokenizerFactory.class),filters = {
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = SnowballPorterFilterFactory.class,
params = {@Parameter(name = "language", value = "Italian")})
})
public class Book {
@Field(index=Index.TOKENIZED, store=Store.NO)
@Analyzer(definition = "italianAnalyzer")
private String title;
...
Altro...
●   @Boost e @DynamicBoost
●   @AnalyzerDiscriminator
●   @DateBridge(resolution=Resolution.MINUTE)
●   @ClassBridge e @FieldBridge
●   @Similarity
●   Automatic Index optimization
Clustering per coda
Clustering per distributed store
Mass (re)indexing
fullTextSession.createIndexer()
   .startAndWait();
Mass (re)indexing

fullTextSession.createIndexer(Hotel.class,
   Person.class,Car.class)
   .threadsForSubsequentFetching( 8 )
   .threadsToLoadObjects( 4 )
   .batchSizeToLoadObjects( 30 )
   .startAndWait();
Futuro prossimo
●   Astrazione delle query Lucene
●   Performance migliorate
    ●   NumericField
    ●   FieldCache
●   Indicizzazione di Pojo non gestiti da Hibernate
●   Infinispan “automagic” clustering
●   Ulteriori opzioni sul MassIndexer
●   Mapping dinamico
Domande?
http://search.hibernate.org
 ● Hibernate Search in Action




http://lucene.apache.org
 ● Lucene In Action (2°ed)




http://in.relation.to

http://forum.hibernate.org

twitter.com/SanneGrinovero

www.sourcesense.com

More Related Content

ODP
NO-HQL at JUG Milano
Sanne Grinovero
 
PDF
Scala Programming Linux Day 2009
Massimiliano Dessì
 
PDF
LINQ, Entities Framework & ORMs
JUG Genova
 
PDF
MS_corso base iOS iPhone_partII
MobileSchool
 
PDF
MongoDB Scala Roma SpringFramework Meeting2009
Massimiliano Dessì
 
PDF
Ajax e jQuery
Emiliano Castellina
 
PPTX
Escape From Amazon: Tips/Techniques for Reducing AWS Dependencies
Soam Acharya
 
PDF
Three languages in thirty minutes
Massimiliano Dessì
 
NO-HQL at JUG Milano
Sanne Grinovero
 
Scala Programming Linux Day 2009
Massimiliano Dessì
 
LINQ, Entities Framework & ORMs
JUG Genova
 
MS_corso base iOS iPhone_partII
MobileSchool
 
MongoDB Scala Roma SpringFramework Meeting2009
Massimiliano Dessì
 
Ajax e jQuery
Emiliano Castellina
 
Escape From Amazon: Tips/Techniques for Reducing AWS Dependencies
Soam Acharya
 
Three languages in thirty minutes
Massimiliano Dessì
 

Viewers also liked (6)

PDF
RESTEasy
Massimiliano Dessì
 
PDF
May 2010 - Infinispan
JBug Italy
 
PDF
MongoDB dessi-codemotion
Massimiliano Dessì
 
PDF
Camel and JBoss
JBug Italy
 
PPTX
Embedding social media to effectively support OU learning with Eric Stoller
Open University
 
PDF
JBoss Wise: breaking barriers to WS testing
JBug Italy
 
May 2010 - Infinispan
JBug Italy
 
MongoDB dessi-codemotion
Massimiliano Dessì
 
Camel and JBoss
JBug Italy
 
Embedding social media to effectively support OU learning with Eric Stoller
Open University
 
JBoss Wise: breaking barriers to WS testing
JBug Italy
 
Ad

Similar to May 2010 - Hibernate search (20)

PDF
EE Incremental Store
firenze-gtug
 
PPT
Esercitazioni Ingegneria 6ed
bibliobioing
 
PDF
Repository pattern
Christian Nastasi
 
PPTX
Custom taxonomies / Custom post type - wordcamp milano 2010
Maurizio Pelizzone
 
PDF
Closure Visto Da Vicino
davide ficano
 
PPT
Faceted Search
Daniele Salvatico
 
PPTX
2014 it - app dev series - 04 - indicizzazione
MongoDB
 
PDF
Jug 30 10 04 Jdo
Massimiliano Dessì
 
PDF
MongoDb and Scala SpringFramework Meeting
guest67beeb9
 
PDF
I motori di_ricerca_2
Francesco Tombolini
 
PDF
Javascript - 4 | WebMaster & WebDesigner
Matteo Magni
 
PDF
How I did it (in .NET): idiomatic Domain Driven Design
Andrea Saltarello
 
PDF
Programming iOS lezione 3
NoDelay Software
 
PPTX
Scala: come recuperare la programmazione funzionale e perché
Edmondo Porcu
 
PPT
Risorse elettroniche per la ricerca 5.ed
bibliobioing
 
PPTX
DNM19 Sessione2 Orchard Temi e Layout (Ita)
Alessandro Giorgetti
 
PPTX
What's new in C# 7
Marco Parenzan
 
PPTX
Entity Framework 6 for developers, Code-First!
Michael Denny
 
ODP
Rich Ajax Web Interfaces in Jquery
Alberto Buschettu
 
PDF
AST 19 - Nittoli - Analisi e ottimizzazione delle SERP
Alessio Nittoli
 
EE Incremental Store
firenze-gtug
 
Esercitazioni Ingegneria 6ed
bibliobioing
 
Repository pattern
Christian Nastasi
 
Custom taxonomies / Custom post type - wordcamp milano 2010
Maurizio Pelizzone
 
Closure Visto Da Vicino
davide ficano
 
Faceted Search
Daniele Salvatico
 
2014 it - app dev series - 04 - indicizzazione
MongoDB
 
Jug 30 10 04 Jdo
Massimiliano Dessì
 
MongoDb and Scala SpringFramework Meeting
guest67beeb9
 
I motori di_ricerca_2
Francesco Tombolini
 
Javascript - 4 | WebMaster & WebDesigner
Matteo Magni
 
How I did it (in .NET): idiomatic Domain Driven Design
Andrea Saltarello
 
Programming iOS lezione 3
NoDelay Software
 
Scala: come recuperare la programmazione funzionale e perché
Edmondo Porcu
 
Risorse elettroniche per la ricerca 5.ed
bibliobioing
 
DNM19 Sessione2 Orchard Temi e Layout (Ita)
Alessandro Giorgetti
 
What's new in C# 7
Marco Parenzan
 
Entity Framework 6 for developers, Code-First!
Michael Denny
 
Rich Ajax Web Interfaces in Jquery
Alberto Buschettu
 
AST 19 - Nittoli - Analisi e ottimizzazione delle SERP
Alessio Nittoli
 
Ad

More from JBug Italy (20)

PDF
AS7 and CLI
JBug Italy
 
PDF
Intro jbug milano_26_set2012
JBug Italy
 
PDF
Faster & Greater Messaging System HornetQ zzz
JBug Italy
 
PDF
Infinispan,Lucene,Hibername OGM
JBug Italy
 
PDF
AS7
JBug Italy
 
ODP
JBoss BRMS - The enterprise platform for business logic
JBug Italy
 
KEY
JBoss AS7 Overview
JBug Italy
 
PDF
Intro JBug Milano - January 2012
JBug Italy
 
PDF
JBoss AS7 Webservices
JBug Italy
 
PDF
JBoss AS7
JBug Italy
 
PDF
Intro JBug Milano - September 2011
JBug Italy
 
ODP
All the cool stuff of JBoss BRMS
JBug Italy
 
ODP
Infinispan and Enterprise Data Grid
JBug Italy
 
PDF
Drools Introduction
JBug Italy
 
PDF
September 2010 - Arquillian
JBug Italy
 
PDF
September 2010 - Gatein
JBug Italy
 
PDF
May 2010 - RestEasy
JBug Italy
 
PDF
May 2010 - Drools flow
JBug Italy
 
ODP
April 2010 - Seam unifies JEE5
JBug Italy
 
PDF
April 2010 - JBoss Web Services
JBug Italy
 
AS7 and CLI
JBug Italy
 
Intro jbug milano_26_set2012
JBug Italy
 
Faster & Greater Messaging System HornetQ zzz
JBug Italy
 
Infinispan,Lucene,Hibername OGM
JBug Italy
 
JBoss BRMS - The enterprise platform for business logic
JBug Italy
 
JBoss AS7 Overview
JBug Italy
 
Intro JBug Milano - January 2012
JBug Italy
 
JBoss AS7 Webservices
JBug Italy
 
JBoss AS7
JBug Italy
 
Intro JBug Milano - September 2011
JBug Italy
 
All the cool stuff of JBoss BRMS
JBug Italy
 
Infinispan and Enterprise Data Grid
JBug Italy
 
Drools Introduction
JBug Italy
 
September 2010 - Arquillian
JBug Italy
 
September 2010 - Gatein
JBug Italy
 
May 2010 - RestEasy
JBug Italy
 
May 2010 - Drools flow
JBug Italy
 
April 2010 - Seam unifies JEE5
JBug Italy
 
April 2010 - JBoss Web Services
JBug Italy
 

May 2010 - Hibernate search