Full text search engines like Apache Lucene™ are a very powerful technology that bring full text and efficient queries to applications. Hibernate Search, which uses Apache Lucene under the covers, indexes your domain model with the addition of a few annotations, takes care of the database / index synchronization and returns regular managed objects that are matched by full text queries. Keep in mind, thought, that there are mismatches that arise when dealing with an object domain model over a text index (keeping the index up to date, mismatch between the index structure and the domain model, and querying mismatch). But the benefits of speed and efficiency far outweigh these limitations.
Apache Lucene™之类的全文搜索引擎能让你的在程序中实现高效的全文搜索功能。Hibernate Search就是基于Apache Lucene™的一个框架。只要你在你的domain model上加几个annotations,它就能替你维护数据库及其索引,并且将符合全文搜索的查询组织成受Hibernate管理的对象返回给你。记住,虽然通过文本索引方式查找出来的对象有可能与实际情况不完全符合(主要是由于构建索引是需要时间的,所以索引与数据库的实际情况可能有一个时间差,从而导致数据不一致),不过通过索引来查找带来的性能上的巨大提升,比这么一点点限制要来的重要多了。
Hibernate Search has been designed to integrates nicely and as naturally as possible with JPA and Hibernate. As a natural extension, JBoss Seam provides an Hibernate Search integration.
Hibernate Search已经能够完美地与JPA以及Hibernate集成。而作为扩展功能,JBoss Seam自然而然也集成了Hibernate Search。
Please refer to the Hibernate Search documentation for information specific to the Hibernate Search project.
如果想获得更多有关Hibernate Search项目的信息,请参阅Hibernate Search文档。
Hibernate Search is configured either in the META-INF/persistence.xml
or hibernate.cfg.xml
file.
Hibernate Search可以在META-INF/persistence.xml中配置,也可以通过hibernate.cfg.xml配置
Hibernate Search configuration has sensible defaults for most configuration parameters. Here is a minimal persistence unit configuration to get started.
Hibernate Search的默认配置中的参数基本上能满足大多数情况。下面我们从配置一个最简单的持久化单元开始。
<persistence-unit name="sample"> <jta-data-source>java:/DefaultDS</jta-data-source> <properties> [...] <!-- use a file system based index --> <property name="hibernate.search.default.directory_provider" value="org.hibernate.search.store.FSDirectoryProvider"/> <!-- directory where the indexes will be stored --> <property name="hibernate.search.default.indexBase" value="/Users/prod/apps/dvdstore/dvdindexes"/> </properties> </persistence-unit>
If you plan to target Hibernate Annotations or EntityManager 3.2.x (embedded into JBoss AS 4.2.GA), you also need to configure the appropriate event listeners.
如果你打算使用Hibernate Annotations或者EntityManager 3.2.x(基于JBoss AS 4.2GA),那么你还需要配置适当的事件监听器。
<persistence-unit name="sample"> <jta-data-source>java:/DefaultDS</jta-data-source> <properties> [...] <!-- use a file system based index --> <property name="hibernate.search.default.directory_provider" value="org.hibernate.search.store.FSDirectoryProvider"/> <!-- directory where the indexes will be stored --> <property name="hibernate.search.default.indexBase" value="/Users/prod/apps/dvdstore/dvdindexes"/> <property name="hibernate.ejb.event.post-insert" value="org.hibernate.search.event.FullTextIndexEventListener"/> <property name="hibernate.ejb.event.post-update" value="org.hibernate.search.event.FullTextIndexEventListener"/> <property name="hibernate.ejb.event.post-delete" value="org.hibernate.search.event.FullTextIndexEventListener"/> </properties> </persistence-unit>
This step is no longer necessary if Hibernate Annotation or EntityManager 3.3.x are used.
如果你使用Hibernate Annotations或者EntityManager 3.3.x,那么这几个步骤就不用再做了。
In addition to the configuration file, the following jars have to be deployed:
除了配置文件之外,还需要加入下面几个jar包:
hibernate-search.jar
hibernate-commons-annotations.jar
lucene-core.jar
If you deploy those in a EAR, don't forget to update application.xml
如果你通过EAR的方式部署项目,那么不要忘了更新application.xml文件。
Hibernate Search uses annotations to map entities to a Lucene index, check the reference documentation for more informations.
Hibernate Search使用Annotations将实体与Lucene索引,具体的信息请参考相关文档。
Hibernate Search is fully integrated with the API and semantic of JPA / Hibernate. Switching from a HQL or Criteria based query requires just a few lines of code. The main API the application interacts with is the FullTextSession
API (subclass of Hibernate's Session
).
Hibernate Search能够完美地融合到JPA/Hibernate的API和语法里面。从HQL或者标准的查询语句切换到Hibernate Search,只需要短短几行代码。程序中用到的主要API为FullTextSession API(Hibernate Session的子类)。
When Hibernate Search is present, JBoss Seam injects a FullTextSession
.
当使用Hibernate Search的时候,需要使用JBoss Seam注入一个FullTextSession。
@Stateful @Name("search") public class FullTextSearchAction implements FullTextSearch, Serializable { @In FullTextSession session; public void search(String searchString) { org.apache.lucene.search.Query luceneQuery = getLuceneQuery(); org.hibernate.Query query session.createFullTextQuery(luceneQuery, Product.class); searchResults = query .setMaxResults(pageSize + 1) .setFirstResult(pageSize * currentPage) .list(); } [...] }
FullTextSession
extends org.hibernate.Session
so that it can be used as a regular Hibernate Session
FullTextSession是继承自org.hibernate.Session,所以,它完全可以当作一个标准的Hibernate Session来使用。
If the Java Persistence API is used, a smoother integration is proposed.
如果使用Java Persistence API,那么集成的工作更加完善。
@Stateful @Name("search") public class FullTextSearchAction implements FullTextSearch, Serializable { @In FullTextEntityManager em; public void search(String searchString) { org.apache.lucene.search.Query luceneQuery = getLuceneQuery(); javax.persistence.Query query = em.createFullTextQuery(luceneQuery, Product.class); searchResults = query .setMaxResults(pageSize + 1) .setFirstResult(pageSize * currentPage) .getResultList(); } [...] }
When Hibernate Search is present, a FulltextEntityManager
is injected. FullTextEntityManager
extends EntityManager
with search specific methods, the same way FullTextSession
extends Session
.
当使用Hibernate Search的时候,会注入一个FulltextEntityManager。FullTextEntityManager继承自EntityManager,情况与FullTextSession继承自Session类似。
When an EJB 3.0 Session or Message Driven Bean injection is used (i.e. via the @PersistenceContext annotation), it is not possible to replace the EntityManager
interface by the FullTextEntityManager
interface in the declaration statement. However, the implementation injected will be a FullTextEntityManager
implementation: downcasting is then possible.
当使用注入的EJB 3.0 Session或者Message Driven Bean的时候(例如通过@PersistenceContext annotation),那么连使用FullTextEntityManager来替代EntityManager都不用。不过实际被注入的仍然是FullTextEntityManager,所以可以在后面去强制转换。
@Stateful @Name("search") public class FullTextSearchAction implements FullTextSearch, Serializable { @PersistenceContext EntityManager em; public void search(String searchString) { org.apache.lucene.search.Query luceneQuery = getLuceneQuery(); FullTextEntityManager ftEm = (FullTextEntityManager) em; javax.persistence.Query query = ftEm.createFullTextQuery(luceneQuery, Product.class); searchResults = query .setMaxResults(pageSize + 1) .setFirstResult(pageSize * currentPage) .getResultList(); } [...] }
For people accustomed to Hibernate Search out of Seam, note that using Search.createFullTextSession
is not necessary.
如果你还没有在Seam中使用过Hibernate Search,那么需要注意,你不再需要使用Search.createFullTextSession。
Check the DVDStore or the blog examples of the JBoss Seam distribution for a concrete use of Hibernate Search.
Seam示例中的DVDStore或者blog示例都使用到了Hibernate Search,具体的应用请参考这两个示例。