Your SlideShare is downloading. ×
0
Java Users Group Sardegna e JBoss Users group Roma
Cagliari 29 Maggio 2010



         HIBERNATE SEARCH
          “Goooogl...
Example database
Search engine: obiettivi
●   Chi cerca non sa cosa sta cercando:
    ●   non è in grado di inserire l'ID dell'oggetto che
...
Idea:
Specifiche “probabili”
●   Campo unico
    ●   Nome autore e/o nome prodotto
    ●   Nome e cognome dell'autore, nomi comp...
SQL è il martello:

String nomeAutore = “Fabrizio De André”
String nomeProdotto = “Nuvole barocche”
List<Prodotti> list = ...
SQL è il martello:

String nomeAutore = “Fabrizio De André”
String nomeProdotto = “Nuvole barocche”
List<Prodotti> list = ...
SQL è il martello:

String nomeAutore = “Fabrizio De André”
String nomeProdotto = “Nuvole barocche”
List<Prodotti> list = ...
E se poi “precisano” le specifiche?
●   Similitudine:
     ●   ʻhybernatʼ
●   Prossimità e sinonimi:
     ●   'JPA' o 'Jav...
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'...
Lucene
●   Similitudine tra termini e documenti
●   Sinonimi
●   Stemming
●   Stopwords
●   TermVectors
●   MoreLikeThis
●...
Similitudine


            Cagliari ⁓ càliari
      Cagliari ⁓ cag agl gli lia ari
            Cagliari ⁓ CGRI
●   N-Grams...
Lucene: Sinonimi (o quasi)


        giornale ⁓ periodico ⁓
              quotidiano

●   Applicabile a “index time”
●   a...
Lucene: Stemming

    parliamone ⁓ parlo
  Velocemente ⁓ velocità

Le grammatiche di stemming sono disponibili
per un'ampi...
Lucene: Stopwords




●   Rimuovono “rumore di fondo” e termini di
    disturbo dall'indice: una ricerca per “non e
    qu...
Può sembrare facile
●   La struttura di un indice è profondamente
    diversa da un modello relazionale.
●   L'indice e il...
Differenze strutturali
 dell'informazione
Incoerenze architetturali
Come integrare Hibernate Search
●   Aggiungere hibernate-search al classpath e dipendenze
<dependency>
   <groupId>org.hib...
Come usare Hibernate Search
@Entity
public class Essay {
   @Id
   public Long getId() { return id; }

   public String ge...
Come usare Hibernate Search
@Entity @Indexed
public class Essay {
   @Id
   public Long getId() { return id; }

   public ...
Come usare Hibernate Search
@Entity @Indexed
public class Essay {
   @Id
   public Long getId() { return id; }
   @Field
 ...
Come usare Hibernate Search
@Entity @Indexed
public class Essay {
   @Id
   public Long getId() { return id; }
   @Field
 ...
Come usare Hibernate Search
@Entity @Indexed
public class Essay {
   @Id
   public Long getId() { return id; }
   @Field
 ...
Altro esempio

@Entity                            @Entity
public class Author {              public class Book {
        @...
Struttura dell'indice

@Entity @Indexed                   @Entity
public class Author {              public class Book {
 ...
Codice di Query:
String[] productFields = {"summary", "author.name"};

QueryParser parser = new MultiFieldQueryParser(prod...
Risultati
●   Pojo gestiti!
●   Paginazione
    ●   .setMaxResults( 20 ).setFirstResult( 100 );
●   Restrizioni per tipo
 ...
Demo / Tests
        org.hibernate.search.test.filter.FilterTest
org.hibernate.search.test.compression.CompressionTest
Filtri

 @Indexed @Entity
 @FullTextFilterDefs( {
    @FullTextFilterDef(name = "disponibiliSubito", impl =      
 ProdDis...
Filtri
FullTextQuery ftQuery = s // s è di tipo FullTextSession
   .createFullTextQuery( query, Prodotto.class )
   .enabl...
Analizzatori custom
@Entity @Indexed
@AnalyzerDef(name = "italianAnalyzer",tokenizer = 
@TokenizerDef(factory=StandardToke...
Altro...
●   @Boost e @DynamicBoost
●   @AnalyzerDiscriminator
●   @DateBridge(resolution=Resolution.MINUTE)
●   @ClassBri...
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(...
Futuro prossimo
●   Astrazione delle query Lucene
●   Performance migliorate
    ●   NumericField
    ●   FieldCache
●   I...
Domande?
http://search.hibernate.org
 ● Hibernate Search in Action




http://lucene.apache.org
 ● Lucene In Action (2°ed)...
Hibernatesearch
Hibernatesearch
Upcoming SlideShare
Loading in...5
×

Hibernatesearch

437

Published on

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
437
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
2
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Transcript of "Hibernatesearch"

  1. 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
  2. 2. Example database
  3. 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!
  4. 4. Idea:
  5. 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. 6. SQL è il martello: String nomeAutore = “Fabrizio De André” String nomeProdotto = “Nuvole barocche” List<Prodotti> list = s.createQuery( “ ...? “ );
  7. 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. 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. 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ù?
  10. 10. Come sarebbe Google se vi restituisse i siti in ordine alfabetico?
  11. 11. Come sarebbe Google se vi restituisse i siti in ordine alfabetico? “hibernate” About 8,320,000 results (0.20 seconds)
  12. 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. 13. Lucene ● Similitudine tra termini e documenti ● Sinonimi ● Stemming ● Stopwords ● TermVectors ● MoreLikeThis ● Faceted Search ● Velocità e scalabilità orizzontale ● ... e naturalmente ricerche full-text.
  14. 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. 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. 16. Lucene: Stemming parliamone ⁓ parlo Velocemente ⁓ velocità Le grammatiche di stemming sono disponibili per un'ampia scelta di lingue, spesso free.
  17. 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. 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?
  19. 19. Differenze strutturali dell'informazione
  20. 20. Incoerenze architetturali
  21. 21. 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
  22. 22. 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; } ...
  23. 23. 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; } ...
  24. 24. 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; } ...
  25. 25. 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; } ...
  26. 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 @IndexedEmbedded     public Author getAuthor() { return author; } ...
  27. 27. 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; }
  28. 28. 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; }
  29. 29. 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)
  30. 30. Risultati ● Pojo gestiti! ● Paginazione ● .setMaxResults( 20 ).setFirstResult( 100 ); ● Restrizioni per tipo ● .createQuery( luceneQuery, A.class, B.class, ..); ● Projection ● Result mapping
  31. 31. Demo / Tests org.hibernate.search.test.filter.FilterTest org.hibernate.search.test.compression.CompressionTest
  32. 32. 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 {    ...
  33. 33. 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();
  34. 34. 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; ...
  35. 35. Altro... ● @Boost e @DynamicBoost ● @AnalyzerDiscriminator ● @DateBridge(resolution=Resolution.MINUTE) ● @ClassBridge e @FieldBridge ● @Similarity ● Automatic Index optimization
  36. 36. Clustering per coda
  37. 37. Clustering per distributed store
  38. 38. Mass (re)indexing fullTextSession.createIndexer()    .startAndWait();
  39. 39. Mass (re)indexing fullTextSession.createIndexer(Hotel.class,    Person.class,Car.class)    .threadsForSubsequentFetching( 8 )    .threadsToLoadObjects( 4 )    .batchSizeToLoadObjects( 30 )    .startAndWait();
  40. 40. 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
  41. 41. 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
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×