閱讀981 返回首頁    go 技術社區[雲棲]


Chapter 1. Getting started

1.3. Configuration

首先是配置開發環境:

主要記錄一下和Hibernate Search 相關的配置,Spring 和 JPA的配置請查看相關文章。

Hibernate Search 的配置相當簡單,主要涉及三個方麵:(本文是基於jpa的)

1、配置Hibernate Search,修改JPA配置文件:persistence.xml

<?xml version="1.0" encoding="utf-8"?>
    <persistence ...>
      <persistence-unit ...>    
          <properties>
            ...
            <!-- hibernate search -->
            <property name="hibernate.search.default.directory_provider" value="filesystem"/>
            <property name="hibernate.search.default.indexBase" value="索引文件存儲位置"/>
        </properties>
      </persistence-unit>
    </persistence>

屬性hibernate.search.default.directory_provider告訴hibernate使用哪個DirectoryProvider實現。在Apache Lucene中有一個概念Directory來保存Index Files。Hibernate通過DirectoryProvider來初始化和配置一個Lucene Directory實例。在本例中,我們使用一個能把Index Files保存在file system中的DirectoryProvider。當Index Files保存在file system中時,我們可以通過Luke工具實時查看Lucene索引文件。除了DirectoryProvider外,還需要告訴hibernate索引文件保存在哪個具體的目錄中,這通過hibernate.search.default.indexBase屬性來配置。

2、添加相應的jar依賴

hibernate-search-4.1.1.Final\dist:
hibernate-search-engine-4.1.1.Final.jar
hibernate-search-orm-4.1.1.Final.jar

hibernate-search-4.1.1.Final\dist\lib\required: 
antlr-2.7.7.jar
avro-1.5.1.jar
dom4j-1.6.1.jar
hibernate-commons-annotations-4.0.1.Final.jar
hibernate-core-4.1.3.Final.jar
jackson-core-asl-1.9.2.jar
jackson-mapper-asl-1.9.2.jar
javassist-3.15.0-GA.jar
jboss-logging-3.1.0.GA.jar
lucene-core-3.5.0.jar
paranamer-2.3.jar
slf4j-api-1.6.1.jar
snappy-java-1.0.1-rc3.jar

3、為實體添加hibernate search 相關annotation

隻需要以上三步,hibernate search就已經配置完成了,接下來要開始實體相關annotation的說明了。




package example;...@Entity
@Indexed
public class Book {

  @Id  @GeneratedValue  private Integer id;    @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
  private String title;    @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
  private String subtitle; 
  @Field(index = Index.YES, analyze=Analyze.NO, store = Store.YES)
  @DateBridge(resolution = Resolution.DAY)
  private Date publicationDate;

  @IndexedEmbedded
  @ManyToMany   private Set<Author> authors = new HashSet<Author>();

  public Book() {  }     // standard getters/setters follow here  ... }
package example;...@Entitypublic class Author {

  @Id  @GeneratedValue  private Integer id;

  @Field
  private String name;

  public Author() {  }    // standard getters/setters follow here  ...}
新建2個實體類
  • @Indexed標注需要索引的實體
  • 如果有@Id標誌,則不需要顯示聲明@DocumentId,因為lucene就不需要生成唯一標誌來區分索引。
  • @Fileld標明為需要搜索的屬性。默認@Filed的參數是index=Index.YESanalyze=Analyze.YES andstore=Store.NO,即進行索引,分詞,不保存具體內容到索引。 Note :無論store=Store.NO還是store=Store.YES都不會影響最終的搜索能力。store.YES的作用是可以在搜索後可以直接從索引中獲取域的完整值。在hibernate中,如果store=Store.NO,搜索結果中,域的值是通過數據庫中獲取,如果store=Store.YES,域的值是直接從索引文檔中獲取。
  • 由於lucene都是基於String進行索引 (Lucene2.9後支持數值索引),所以hibernate search使用@Bridge標簽來轉換數據類型,比如@DateBridge,時間數據轉換
  • 由於lucene索引是平整的數據結構(flat data structure),無法識別對象關聯關係@ManyToMany,@*ToOne@Embedded and@ElementCollection,hibernate search,為了讓上麵的書的作者能被識別,使用@IndexedEmbedded標簽

1.4. Indexing

hibernate search會透明的索引所有有標注過的實體類,不管是更新還是刪除,都通過hibernate core自動進行。
但是如果數據庫中已經有數據,則需手動初始化你的索引。如下(see also Section 6.3, “Rebuilding the whole index”):
  1. //使用Hibernate Session初始化索引  
  2. FullTextSession fullTextSession = Search.getFullTextSession(session);  
  3. fullTextSession.createIndexer().startAndWait();  
 
Java代碼  
  1. //使用JPA初始化索引  
  2. EntityManager em = entityManagerFactory.createEntityManager();  
  3. FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);  
  4. fullTextEntityManager.createIndexer().startAndWait();  
上述操作之後,就可以在索引目錄中看到新生成的索引.利用luke查看索引,可以更好的了解lucene是如何工作的。

通過Hibernate Search query DSL,

Hibernate Session創建和運行搜索

Java代碼  
  1. FullTextSession fullTextSession = Search.getFullTextSession(session);  
  2. Transaction tx = fullTextSession.beginTransaction();  
  3. // create native Lucene query unsing the query DSL  
  4. // alternatively you can write the Lucene query using the Lucene query parser  
  5. // or the Lucene programmatic API. The Hibernate Search DSL is recommended though  
  6. QueryBuilder qb = fullTextSession.getSearchFactory()  
  7.     .buildQueryBuilder().forEntity( Book.class ).get();  
  8. org.apache.lucene.search.Query query = qb  
  9.   .keyword()  
  10.   .onFields("title""subtitle""authors.name""publicationDate")  
  11.   .matching("Java rocks!")  
  12.  .createQuery();  
  13. // wrap Lucene query in a org.hibernate.Query  
  14. org.hibernate.Query hibQuery =   
  15.     fullTextSession.createFullTextQuery(query, Book.class);  
  16. // execute search  
  17. List result = hibQuery.list();  
  18.     
  19. tx.commit();  
  20. session.close();  
 

通過JPA創建和運行搜索

Java代碼  
  1. EntityManager em = entityManagerFactory.createEntityManager();  
  2. FullTextEntityManager fullTextEntityManager =   
  3.     org.hibernate.search.jpa.Search.getFullTextEntityManager(em);  
  4. em.getTransaction().begin();  
  5. // create native Lucene query unsing the query DSL  
  6. // alternatively you can write the Lucene query using the Lucene query parser  
  7. // or the Lucene programmatic API. The Hibernate Search DSL is recommended though  
  8. QueryBuilder qb = fullTextSession.getSearchFactory()  
  9.     .buildQueryBuilder().forEntity( Book.class ).get();  
  10. org.apache.lucene.search.Query query = qb  
  11.   .keyword()  
  12.   .onFields("title""subtitle""authors.name""publicationDate")  
  13.   .matching("Java rocks!");  
  14.   .createQuery();  
  15. // wrap Lucene query in a javax.persistence.Query  
  16. javax.persistence.Query persistenceQuery =   
  17.     fullTextEntityManager.createFullTextQuery(query, Book.class);  
  18. // execute search  
  19. List result = persistenceQuery.getResultList();  
  20. em.getTransaction().commit();  
  21. em.close();   

1.6. Analyzer


  • 在配置文件中設置 默認分詞器hibernate.search.analyzer

  • 用標注的方式在實體上設置分詞器 @Analyzer .

  • 用標注的方式在field域上設置分詞器 @Analyzer .

我們也可以利用@AnalyzerDef自定義分詞器,接下來的例子將結合Solr分詞器以及factories,更多的
可使用factory類詳見Solr文檔,Solr Wiki.
下麵的例子使用StandardTokenizerFactory,以及2個filter factories,LowerCaseFilterFactory andSnowballPorterFilterFactory.標準的分詞器通過會標點符號和連接符進行分詞,以便保持email和主機名的
完整。lowercase filter將所有字母轉化為小寫,最後由snowball filter進行截詞

通常來說,使用Solr必須先聲明分詞器以及過濾器.

Example 1.11. Using @AnalyzerDef and the Solr framework to define and use an analyzer
@Entity@Indexed
@AnalyzerDef(name = "customanalyzer",
  tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
  filters = {
    @TokenFilterDef(factory = LowerCaseFilterFactory.class),
    @TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = {
      @Parameter(name = "language", value = "English")
    })
  })
public class Book {

  @Id  @GeneratedValue  @DocumentId  private Integer id;    @Field  @Analyzer(definition = "customanalyzer")
  private String title;    @Field  @Analyzer(definition = "customanalyzer")
  private String subtitle; 

  @IndexedEmbedded  @ManyToMany   private Set<Author> authors = new HashSet<Author>();
  @Field(index = Index.YES, analyze = Analyze.NO, store = Store.YES)  @DateBridge(resolution = Resolution.DAY)  private Date publicationDate;    public Book() {  }     // standard getters/setters follow here  ... }
使用@AnalyzerDef隻是定義了一個分析器,你仍然需要使用通過標注@Analyzer來使用它,就像上麵的例子,customanalyzer
被應用在title和subtitle屬性上。analyzer的定義是全局性的,一旦定義之後就可以在所有實體上使用。



第一章結束,排版很蛋疼,這也就是我為什麼不喜歡在論壇上發帖- -。

最後更新:2017-04-03 18:52:02

  上一篇:go 服務器序列號查詢備忘
  下一篇:go 基於lucene搜索引擎的Hibernate Search,官方文檔翻譯