SlideShare une entreprise Scribd logo
1  sur  43
Télécharger pour lire hors ligne
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
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
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

Contenu connexe

Similaire à Hibernatesearch

EE Incremental Store
EE Incremental StoreEE Incremental Store
EE Incremental Storefirenze-gtug
 
Esercitazioni Ingegneria 6ed
Esercitazioni Ingegneria 6edEsercitazioni Ingegneria 6ed
Esercitazioni Ingegneria 6edbibliobioing
 
Custom taxonomies / Custom post type - wordcamp milano 2010
Custom taxonomies / Custom post type - wordcamp milano 2010Custom taxonomies / Custom post type - wordcamp milano 2010
Custom taxonomies / Custom post type - wordcamp milano 2010Maurizio Pelizzone
 
Closure Visto Da Vicino
Closure Visto Da VicinoClosure Visto Da Vicino
Closure Visto Da Vicinodavide ficano
 
2014 it - app dev series - 04 - indicizzazione
2014   it - app dev series - 04 - indicizzazione2014   it - app dev series - 04 - indicizzazione
2014 it - app dev series - 04 - indicizzazioneMongoDB
 
MongoDb and Scala SpringFramework Meeting
MongoDb and Scala SpringFramework MeetingMongoDb and Scala SpringFramework Meeting
MongoDb and Scala SpringFramework Meetingguest67beeb9
 
Javascript - 4 | WebMaster & WebDesigner
Javascript - 4 | WebMaster & WebDesignerJavascript - 4 | WebMaster & WebDesigner
Javascript - 4 | WebMaster & WebDesignerMatteo Magni
 
How I did it (in .NET): idiomatic Domain Driven Design
How I did it (in .NET): idiomatic Domain Driven DesignHow I did it (in .NET): idiomatic Domain Driven Design
How I did it (in .NET): idiomatic Domain Driven DesignAndrea Saltarello
 
Scala: come recuperare la programmazione funzionale e perché
Scala: come recuperare la programmazione funzionale e perchéScala: come recuperare la programmazione funzionale e perché
Scala: come recuperare la programmazione funzionale e perchéEdmondo Porcu
 
Risorse elettroniche per la ricerca 5.ed
Risorse elettroniche per la ricerca 5.edRisorse elettroniche per la ricerca 5.ed
Risorse elettroniche per la ricerca 5.edbibliobioing
 
DNM19 Sessione2 Orchard Temi e Layout (Ita)
DNM19 Sessione2 Orchard Temi e Layout (Ita)DNM19 Sessione2 Orchard Temi e Layout (Ita)
DNM19 Sessione2 Orchard Temi e Layout (Ita)Alessandro Giorgetti
 
Entity Framework 6 for developers, Code-First!
Entity Framework 6 for developers, Code-First!Entity Framework 6 for developers, Code-First!
Entity Framework 6 for developers, Code-First!Michael Denny
 
Rich Ajax Web Interfaces in Jquery
Rich Ajax Web Interfaces in JqueryRich Ajax Web Interfaces in Jquery
Rich Ajax Web Interfaces in JqueryAlberto Buschettu
 
AST 19 - Nittoli - Analisi e ottimizzazione delle SERP
AST 19 - Nittoli - Analisi e ottimizzazione delle SERPAST 19 - Nittoli - Analisi e ottimizzazione delle SERP
AST 19 - Nittoli - Analisi e ottimizzazione delle SERPAlessio Nittoli
 

Similaire à Hibernatesearch (20)

EE Incremental Store
EE Incremental StoreEE Incremental Store
EE Incremental Store
 
Esercitazioni Ingegneria 6ed
Esercitazioni Ingegneria 6edEsercitazioni Ingegneria 6ed
Esercitazioni Ingegneria 6ed
 
Repository pattern
Repository patternRepository pattern
Repository pattern
 
Custom taxonomies / Custom post type - wordcamp milano 2010
Custom taxonomies / Custom post type - wordcamp milano 2010Custom taxonomies / Custom post type - wordcamp milano 2010
Custom taxonomies / Custom post type - wordcamp milano 2010
 
Closure Visto Da Vicino
Closure Visto Da VicinoClosure Visto Da Vicino
Closure Visto Da Vicino
 
Faceted Search
Faceted SearchFaceted Search
Faceted Search
 
2014 it - app dev series - 04 - indicizzazione
2014   it - app dev series - 04 - indicizzazione2014   it - app dev series - 04 - indicizzazione
2014 it - app dev series - 04 - indicizzazione
 
Jug 30 10 04 Jdo
Jug 30 10 04 JdoJug 30 10 04 Jdo
Jug 30 10 04 Jdo
 
MongoDb and Scala SpringFramework Meeting
MongoDb and Scala SpringFramework MeetingMongoDb and Scala SpringFramework Meeting
MongoDb and Scala SpringFramework Meeting
 
I motori di_ricerca_2
I motori di_ricerca_2I motori di_ricerca_2
I motori di_ricerca_2
 
Javascript - 4 | WebMaster & WebDesigner
Javascript - 4 | WebMaster & WebDesignerJavascript - 4 | WebMaster & WebDesigner
Javascript - 4 | WebMaster & WebDesigner
 
How I did it (in .NET): idiomatic Domain Driven Design
How I did it (in .NET): idiomatic Domain Driven DesignHow I did it (in .NET): idiomatic Domain Driven Design
How I did it (in .NET): idiomatic Domain Driven Design
 
Programming iOS lezione 3
Programming iOS lezione 3Programming iOS lezione 3
Programming iOS lezione 3
 
Scala: come recuperare la programmazione funzionale e perché
Scala: come recuperare la programmazione funzionale e perchéScala: come recuperare la programmazione funzionale e perché
Scala: come recuperare la programmazione funzionale e perché
 
Risorse elettroniche per la ricerca 5.ed
Risorse elettroniche per la ricerca 5.edRisorse elettroniche per la ricerca 5.ed
Risorse elettroniche per la ricerca 5.ed
 
DNM19 Sessione2 Orchard Temi e Layout (Ita)
DNM19 Sessione2 Orchard Temi e Layout (Ita)DNM19 Sessione2 Orchard Temi e Layout (Ita)
DNM19 Sessione2 Orchard Temi e Layout (Ita)
 
What's new in C# 7
What's new in C# 7What's new in C# 7
What's new in C# 7
 
Entity Framework 6 for developers, Code-First!
Entity Framework 6 for developers, Code-First!Entity Framework 6 for developers, Code-First!
Entity Framework 6 for developers, Code-First!
 
Rich Ajax Web Interfaces in Jquery
Rich Ajax Web Interfaces in JqueryRich Ajax Web Interfaces in Jquery
Rich Ajax Web Interfaces in Jquery
 
AST 19 - Nittoli - Analisi e ottimizzazione delle SERP
AST 19 - Nittoli - Analisi e ottimizzazione delle SERPAST 19 - Nittoli - Analisi e ottimizzazione delle SERP
AST 19 - Nittoli - Analisi e ottimizzazione delle SERP
 

Hibernatesearch