• hibernate search 和lucene结合使用实例


    以下的代码是根据api帮助文档作出的一个简单实例,在应用方面可以实现创建索引,搜索,过滤和高亮的功能。

    整体的环境为:spring2.5.6,hibernate3.3.1,struts2.0.8,lucene2.4.1

    第一步,首先是web.xml配置文件,由于使用了ssh2的架构,所以不得不在web.xml里配置一些东西

    Java代码 复制代码
    1. ]<?xml version="1.0" encoding="UTF-8"?>   
    2. <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"  
    3.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    4.  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    
    5.  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">   
    6.   
    7.  <!-- spring的配置文件路径 -->   
    8.  <context-param>   
    9.   <param-name>contextConfigLocation</param-name>   
    10.   <param-value>classpath*:spring/*.xml</param-value>   
    11.  </context-param>   
    12.     
    13.  <!--Hibernate Open Session in View Filter-->   
    14.  <filter>   
    15.   <filter-name>hibernateFilter</filter-name>   
    16.   <filter-class>   
    17.    org.springframework.orm.hibernate3.support.OpenSessionInViewFilter   
    18.   </filter-class>   
    19.  </filter>   
    20.  <filter-mapping>   
    21.   <filter-name>hibernateFilter</filter-name>   
    22.   <url-pattern>*.action</url-pattern>   
    23.   <dispatcher>REQUEST</dispatcher>   
    24.   <dispatcher>FORWARD</dispatcher>   
    25.  </filter-mapping>   
    26.  <filter-mapping>   
    27.   <filter-name>hibernateFilter</filter-name>   
    28.   <url-pattern>*.jsp</url-pattern>   
    29.   <dispatcher>REQUEST</dispatcher>   
    30.   <dispatcher>FORWARD</dispatcher>   
    31.  </filter-mapping>   
    32.     
    33.  <listener>   
    34.   <listener-class>   
    35.    org.springframework.web.context.ContextLoaderListener   
    36.   </listener-class>   
    37.  </listener>   
    38.   
    39.  <!-- Spring 刷新Introspector防止内存泄露 -->   
    40.  <listener>   
    41.   <listener-class>   
    42.    org.springframework.web.util.IntrospectorCleanupListener   
    43.   </listener-class>   
    44.  </listener>   
    45.   
    46.  <!-- Struts Action Mapping-->   
    47.  <filter>   
    48.   <filter-name>struts-cleanup</filter-name>   
    49.   <filter-class>   
    50.    org.apache.struts2.dispatcher.ActionContextCleanUp   
    51.   </filter-class>   
    52.  </filter>   
    53.  <filter>   
    54.   <filter-name>struts2</filter-name>   
    55.   <filter-class>   
    56.    org.apache.struts2.dispatcher.FilterDispatcher   
    57.   </filter-class>   
    58.  </filter>   
    59.   
    60.  <filter-mapping>   
    61.   <filter-name>struts-cleanup</filter-name>   
    62.   <url-pattern>/*</url-pattern>   
    63.  </filter-mapping>    
    64.  <filter-mapping>   
    65.   <filter-name>struts2</filter-name>   
    66.   <url-pattern>*.jsp</url-pattern>   
    67.   <dispatcher>REQUEST</dispatcher>   
    68.   <dispatcher>FORWARD</dispatcher>   
    69.  </filter-mapping>   
    70.  <filter-mapping>   
    71.   <filter-name>struts2</filter-name>   
    72.   <url-pattern>*.action</url-pattern>   
    73.   <dispatcher>REQUEST</dispatcher>   
    74.   <dispatcher>FORWARD</dispatcher>   
    75.  </filter-mapping>   
    76.   
    77. <!-- spring自带的字符转换过滤器,转换成utf-8的格式 -->   
    78.  <filter>   
    79.   <filter-name>encodingFilter</filter-name>   
    80.   <filter-class>   
    81.    org.springframework.web.filter.CharacterEncodingFilter   
    82.   </filter-class>   
    83.   <init-param>   
    84.    <param-name>encoding</param-name>   
    85.    <param-value>UTF-8</param-value>   
    86.   </init-param>   
    87.  </filter>   
    88.  <filter-mapping>   
    89.   <filter-name>encodingFilter</filter-name>   
    90.   <url-pattern>/*</url-pattern>   
    91.  </filter-mapping>   
    92.   
    93.  <!-- 随服务器启动,自动调用对应的servlet创建索引文件 -->   
    94.   
    95.  <servlet>   
    96.   <servlet-name>CreateHibernateIndex</servlet-name>   
    97.   <servlet-class>com.test.servlet.CreateHibernateIndex</servlet-class>   
    98.   <load-on-startup>20</load-on-startup>   
    99.  </servlet>   
    100.  <servlet-mapping>   
    101.   <servlet-name>CreateHibernateIndex</servlet-name>   
    102.   <url-pattern>/servlet/CreateHibernateIndex</url-pattern>   
    103.  </servlet-mapping>   
    104.   
    105.  <!-- session超时定义,单位为分钟 -->   
    106.  <session-config>   
    107.   <session-timeout>20</session-timeout>   
    108.  </session-config>   
    109.  <!-- 默认首页定义 -->   
    110.  <welcome-file-list>   
    111.   <welcome-file>/index.jsp</welcome-file>   
    112.  </welcome-file-list>   
    113.   
    114. </web-app>  
    ]<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- spring的配置文件路径 --> <context-param>  <param-name>contextConfigLocation</param-name>  <param-value>classpath*:spring/*.xml</param-value> </context-param>  <!--Hibernate Open Session in View Filter--> <filter>  <filter-name>hibernateFilter</filter-name>  <filter-class>   org.springframework.orm.hibernate3.support.OpenSessionInViewFilter  </filter-class> </filter> <filter-mapping>  <filter-name>hibernateFilter</filter-name>  <url-pattern>*.action</url-pattern>  <dispatcher>REQUEST</dispatcher>  <dispatcher>FORWARD</dispatcher> </filter-mapping> <filter-mapping>  <filter-name>hibernateFilter</filter-name>  <url-pattern>*.jsp</url-pattern>  <dispatcher>REQUEST</dispatcher>  <dispatcher>FORWARD</dispatcher> </filter-mapping>  <listener>  <listener-class>   org.springframework.web.context.ContextLoaderListener  </listener-class> </listener> <!-- Spring 刷新Introspector防止内存泄露 --> <listener>  <listener-class>   org.springframework.web.util.IntrospectorCleanupListener  </listener-class> </listener> <!-- Struts Action Mapping--> <filter>  <filter-name>struts-cleanup</filter-name>  <filter-class>   org.apache.struts2.dispatcher.ActionContextCleanUp  </filter-class> </filter> <filter>  <filter-name>struts2</filter-name>  <filter-class>   org.apache.struts2.dispatcher.FilterDispatcher  </filter-class> </filter> <filter-mapping>  <filter-name>struts-cleanup</filter-name>  <url-pattern>/*</url-pattern> </filter-mapping>  <filter-mapping>  <filter-name>struts2</filter-name>  <url-pattern>*.jsp</url-pattern>  <dispatcher>REQUEST</dispatcher>  <dispatcher>FORWARD</dispatcher> </filter-mapping> <filter-mapping>  <filter-name>struts2</filter-name>  <url-pattern>*.action</url-pattern>  <dispatcher>REQUEST</dispatcher>  <dispatcher>FORWARD</dispatcher> </filter-mapping><!-- spring自带的字符转换过滤器,转换成utf-8的格式 --> <filter>  <filter-name>encodingFilter</filter-name>  <filter-class>   org.springframework.web.filter.CharacterEncodingFilter  </filter-class>  <init-param>   <param-name>encoding</param-name>   <param-value>UTF-8</param-value>  </init-param> </filter> <filter-mapping>  <filter-name>encodingFilter</filter-name>  <url-pattern>/*</url-pattern> </filter-mapping> <!-- 随服务器启动,自动调用对应的servlet创建索引文件 --> <servlet>  <servlet-name>CreateHibernateIndex</servlet-name>  <servlet-class>com.test.servlet.CreateHibernateIndex</servlet-class>  <load-on-startup>20</load-on-startup> </servlet> <servlet-mapping>  <servlet-name>CreateHibernateIndex</servlet-name>  <url-pattern>/servlet/CreateHibernateIndex</url-pattern> </servlet-mapping> <!-- session超时定义,单位为分钟 --> <session-config>  <session-timeout>20</session-timeout> </session-config> <!-- 默认首页定义 --> <welcome-file-list>  <welcome-file>/index.jsp</welcome-file> </welcome-file-list></web-app>


    第二步,配spring配置文件和hibernate文件

    这是可以使用hibernate annotation注释的sessionFactory的属性配置的一部分,注意下面的2个使用索引的属性配置,提供文件索引的保存路径和读取方式(fsdirectory,文件索引,另外一种是ramdirectory,内存索引)

    Java代码 复制代码
    1. <prop   
    2.      key="hibernate.search.default.directory_provider">   
    3.      org.hibernate.search.store.FSDirectoryProvider   
    4.     </prop>   
    5.     <prop key="hibernate.search.default.indexBase">   
    6.      ${hibernate.search.default.indexBase}   
    7.     </prop>  
    <prop     key="hibernate.search.default.directory_provider">     org.hibernate.search.store.FSDirectoryProvider    </prop>    <prop key="hibernate.search.default.indexBase">     ${hibernate.search.default.indexBase}    </prop>


       
    spring的配置文件没有什么特别的,和普通ssh配置没有什么两样

    第三步配struts配置文件,由于也是普通配置,没有特别之处,就不贴出来了。

    第四步,写实体类,由于采用hibernate search方法搜索,所以直接利用hibernate annotation注释去定义索引的一些配置信息。关于index的基本都属于索引的配置

    Java代码 复制代码
    1. package com.test.model;   
    2.   
    3. import static javax.persistence.GenerationType.IDENTITY;   
    4.   
    5. import java.util.Date;   
    6.   
    7. import javax.persistence.Column;   
    8. import javax.persistence.Entity;   
    9. import javax.persistence.GeneratedValue;   
    10. import javax.persistence.Id;   
    11. import javax.persistence.Table;   
    12. import javax.persistence.Temporal;   
    13. import javax.persistence.TemporalType;   
    14. import javax.persistence.Transient;   
    15.   
    16. import org.hibernate.search.annotations.Analyzer;   
    17. import org.hibernate.search.annotations.DateBridge;   
    18. import org.hibernate.search.annotations.DocumentId;   
    19. import org.hibernate.search.annotations.Field;   
    20. import org.hibernate.search.annotations.Index;   
    21. import org.hibernate.search.annotations.Indexed;   
    22. import org.hibernate.search.annotations.Resolution;   
    23. import org.hibernate.search.annotations.Store;   
    24. import org.wltea.analyzer.lucene.IKAnalyzer;   
    25.   
    26.   
    27. /**  
    28.  * Product entity.  
    29.  */  
    30. @Entity  
    31. @Table(name = "product", catalog = "hibernate_search_test")   
    32. @Indexed(index = "Product")   
    33. @Analyzer (impl = IKAnalyzer.class )    
    34. public class Product implements java.io.Serializable {   
    35.   
    36.  // Fields   
    37.   
    38.  /**  
    39.   *   
    40.   */  
    41.  private static final long serialVersionUID = -7005490272739421758L;   
    42.  private Integer id;   
    43.  private String proTitle;   
    44.  private String proDescn;   
    45.  private String proPrice;   
    46.  private Integer proType;   
    47.  private Date proTime;   
    48.  private String findResult;   
    49.   
    50.  // Constructors   
    51.   
    52.  /** default constructor */  
    53.  public Product() {   
    54.  }   
    55.   
    56.  // Property accessors   
    57.  @Id  
    58.  @GeneratedValue(strategy = IDENTITY)   
    59.  @Column(name = "id")   
    60.  @DocumentId    
    61.  public Integer getId() {   
    62.   return this.id;   
    63.  }   
    64.   
    65.  public void setId(Integer id) {   
    66.   this.id = id;   
    67.  }   
    68.   
    69.  @Column(name = "pro_title")   
    70.  @Field(name = "pt", index = Index.TOKENIZED, store = Store.YES)   
    71.  public String getProTitle() {   
    72.   return this.proTitle;   
    73.  }   
    74.   
    75.  public void setProTitle(String proTitle) {   
    76.   this.proTitle = proTitle;   
    77.  }   
    78.   
    79.  @Column(name = "pro_descn")   
    80.  @Field(name = "pd", index = Index.TOKENIZED, store = Store.YES)   
    81.  public String getProDescn() {   
    82.   return this.proDescn;   
    83.  }   
    84.   
    85.  public void setProDescn(String proDescn) {   
    86.   this.proDescn = proDescn;   
    87.  }   
    88.   
    89.  @Column(name = "pro_price")   
    90.  public String getProPrice() {   
    91.   return this.proPrice;   
    92.  }   
    93.   
    94.  public void setProPrice(String proPrice) {   
    95.   this.proPrice = proPrice;   
    96.  }   
    97.   
    98.  @Column(name = "pro_type")   
    99.  public Integer getProType() {   
    100.   return this.proType;   
    101.  }   
    102.   
    103.  public void setProType(Integer proType) {   
    104.   this.proType = proType;   
    105.  }   
    106.   
    107.  @Temporal(TemporalType.DATE)   
    108.  @Column(name = "pro_time")   
    109.  @Field(name = "t", index = Index.UN_TOKENIZED, store = Store.YES)   
    110.  @DateBridge(resolution = Resolution.DAY)   
    111.  public Date getProTime() {   
    112.   return this.proTime;   
    113.  }   
    114.   
    115.  public void setProTime(Date proTime) {   
    116.   this.proTime = proTime;   
    117.  }   
    118.   
    119. //封装搜索出的高亮内容   
    120.  @Transient  
    121.  public String getFindResult() {   
    122.   return findResult;   
    123.  }   
    124.   
    125.  public void setFindResult(String findResult) {   
    126.   this.findResult = findResult;   
    127.  }   
    128. }  
    package com.test.model;import static javax.persistence.GenerationType.IDENTITY;import java.util.Date;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.Table;import javax.persistence.Temporal;import javax.persistence.TemporalType;import javax.persistence.Transient;import org.hibernate.search.annotations.Analyzer;import org.hibernate.search.annotations.DateBridge;import org.hibernate.search.annotations.DocumentId;import org.hibernate.search.annotations.Field;import org.hibernate.search.annotations.Index;import org.hibernate.search.annotations.Indexed;import org.hibernate.search.annotations.Resolution;import org.hibernate.search.annotations.Store;import org.wltea.analyzer.lucene.IKAnalyzer;/** * Product entity. */@Entity@Table(name = "product", catalog = "hibernate_search_test")@Indexed(index = "Product")@Analyzer (impl = IKAnalyzer.class ) public class Product implements java.io.Serializable { // Fields /**  *   */ private static final long serialVersionUID = -7005490272739421758L; private Integer id; private String proTitle; private String proDescn; private String proPrice; private Integer proType; private Date proTime; private String findResult; // Constructors /** default constructor */ public Product() { } // Property accessors @Id @GeneratedValue(strategy = IDENTITY) @Column(name = "id") @DocumentId  public Integer getId() {  return this.id; } public void setId(Integer id) {  this.id = id; } @Column(name = "pro_title") @Field(name = "pt", index = Index.TOKENIZED, store = Store.YES) public String getProTitle() {  return this.proTitle; } public void setProTitle(String proTitle) {  this.proTitle = proTitle; } @Column(name = "pro_descn") @Field(name = "pd", index = Index.TOKENIZED, store = Store.YES) public String getProDescn() {  return this.proDescn; } public void setProDescn(String proDescn) {  this.proDescn = proDescn; } @Column(name = "pro_price") public String getProPrice() {  return this.proPrice; } public void setProPrice(String proPrice) {  this.proPrice = proPrice; } @Column(name = "pro_type") public Integer getProType() {  return this.proType; } public void setProType(Integer proType) {  this.proType = proType; } @Temporal(TemporalType.DATE) @Column(name = "pro_time") @Field(name = "t", index = Index.UN_TOKENIZED, store = Store.YES) @DateBridge(resolution = Resolution.DAY) public Date getProTime() {  return this.proTime; } public void setProTime(Date proTime) {  this.proTime = proTime; }//封装搜索出的高亮内容 @Transient public String getFindResult() {  return findResult; } public void setFindResult(String findResult) {  this.findResult = findResult; }}


    第六步,写service方法,包括建索引,根据关键字用索引查,过滤,设置权重,高亮等等工作

    Java代码 复制代码
    1. package com.test.service;   
    2.   
    3. import java.io.File;   
    4. import java.io.StringReader;   
    5. import java.util.Date;   
    6. import java.util.List;   
    7.   
    8. import javax.annotation.Resource;   
    9.   
    10. import org.apache.lucene.analysis.Analyzer;   
    11. import org.apache.lucene.analysis.Token;   
    12. import org.apache.lucene.analysis.TokenStream;   
    13. import org.apache.lucene.document.DateTools;   
    14. import org.apache.lucene.document.Document;   
    15. import org.apache.lucene.document.Field;   
    16. import org.apache.lucene.document.DateTools.Resolution;   
    17. import org.apache.lucene.index.IndexReader;   
    18. import org.apache.lucene.index.IndexWriter;   
    19. import org.apache.lucene.index.Term;   
    20. import org.apache.lucene.queryParser.QueryParser;   
    21. import org.apache.lucene.search.BooleanClause;   
    22. import org.apache.lucene.search.BooleanQuery;   
    23. import org.apache.lucene.search.CachingWrapperFilter;   
    24. import org.apache.lucene.search.Filter;   
    25. import org.apache.lucene.search.IndexSearcher;   
    26. import org.apache.lucene.search.Query;   
    27. import org.apache.lucene.search.QueryWrapperFilter;   
    28. import org.apache.lucene.search.ScoreDoc;   
    29. import org.apache.lucene.search.TermQuery;   
    30. import org.apache.lucene.search.TermRangeQuery;   
    31. import org.apache.lucene.search.TopScoreDocCollector;   
    32. import org.apache.lucene.search.BooleanClause.Occur;   
    33. import org.apache.lucene.search.highlight.Formatter;   
    34. import org.apache.lucene.search.highlight.Highlighter;   
    35. import org.apache.lucene.search.highlight.QueryScorer;   
    36. import org.apache.lucene.search.highlight.SimpleFragmenter;   
    37. import org.apache.lucene.search.highlight.SimpleHTMLFormatter;   
    38. import org.apache.lucene.store.FSDirectory;   
    39. import org.apache.lucene.util.Version;   
    40. import org.hibernate.CacheMode;   
    41. import org.hibernate.FlushMode;   
    42. import org.hibernate.ScrollMode;   
    43. import org.hibernate.ScrollableResults;   
    44. import org.hibernate.search.FullTextQuery;   
    45. import org.hibernate.search.FullTextSession;   
    46. import org.hibernate.search.Search;   
    47. import org.springframework.context.ApplicationContext;   
    48. import org.springframework.context.support.ClassPathXmlApplicationContext;   
    49. import org.springframework.stereotype.Service;   
    50. import org.springframework.transaction.annotation.Transactional;   
    51. import org.springside.modules.orm.hibernate.HibernateDao;   
    52. import org.springside.modules.service.EntityManager;   
    53. import org.wltea.analyzer.lucene.IKAnalyzer;   
    54.   
    55. import com.test.dao.ProductDao;   
    56. import com.test.model.Product;   
    57.   
    58. @Transactional  
    59. @Service  
    60. public class ProductService extends EntityManager<Product, Integer> {   
    61.  @Resource(name = "productDao")   
    62.  private ProductDao productDao;   
    63.   
    64.  @Override  
    65.  protected HibernateDao<Product, Integer> getEntityDao() {   
    66.   // TODO Auto-generated method stub   
    67.   return productDao;   
    68.  }   
    69.   
    70.  @SuppressWarnings("unchecked")   
    71.  public List<Product> QueryByIndex(String words, String startDate,String endDate) throws Exception {   
    72.   FullTextSession fullTextSession = Search.createFullTextSession(productDao.getSession());   
    73.   
    74.   /*Query IKQuery = IKQueryParser.parseMultiField(new String[] {  
    75.     "proTitle", "proDescn" }, new String[] { words, words },  
    76.     new BooleanClause.Occur[] { Occur.SHOULD, Occur.SHOULD });  
    77.  
    78.   Query luceneQuery = MultiFieldQueryParser.parse(new String[] { words,  
    79.     words }, new String[] { "pro_title", "pro_descn" },  
    80.     new BooleanClause.Occur[] { Occur.SHOULD, Occur.SHOULD },  
    81.     new StandardAnalyzer());*/  
    82.   BooleanQuery bQuery = new BooleanQuery();   
    83.   Analyzer analyzer = new IKAnalyzer();   
    84.   //设置对域采用的某种分词器的QueryParser对象   
    85.   QueryParser qp;   
    86.   //设置了关键字的查询您对象   
    87.   //Query q;   
    88.      
    89.   qp = new QueryParser(Version.LUCENE_CURRENT,"pt",analyzer);   
    90.   Query q1 = qp.parse(words);   
    91.   q1.setBoost(1.5f);   
    92.   bQuery.add(q1, Occur.SHOULD);   
    93.      
    94.   qp = new QueryParser(Version.LUCENE_CURRENT,"pd",analyzer);   
    95.   Query q2 = qp.parse(words);   
    96.   q2.setBoost(1.0f);   
    97.   bQuery.add(q2, Occur.SHOULD);   
    98.      
    99.   FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(bQuery,Product.class);   
    100.   // 添加是或者否的条件到query中   
    101.   boolean filterResult = false;   
    102.   BooleanQuery bQueryForFilter = new BooleanQuery();   
    103.   
    104.   if (!startDate.equalsIgnoreCase("") && !endDate.equalsIgnoreCase("")) {   
    105.    // 时间过滤   
    106.    // RangeFilter rangefilter = new RangeFilter("pro_time",   
    107.    // "20090927","20090929", false, false);   
    108.    // 只能使用一个过滤器,所以只能用下面的RangeQuery,然后将所有query封装到一个过滤条件中   
    109.    TermRangeQuery rangeQuery = new TermRangeQuery("t",startDate,endDate,true,true);   
    110.    bQueryForFilter.add(rangeQuery, BooleanClause.Occur.MUST);   
    111.    filterResult = true;   
    112.   }   
    113.   if (filterResult) {   
    114.    // 将booleanQuery封装到Filter中   
    115.    Filter filter = new CachingWrapperFilter(new QueryWrapperFilter(bQueryForFilter));   
    116.    fullTextQuery.setFilter(filter);   
    117.   }   
    118.      
    119.   List<Product> result = fullTextQuery.list();   
    120.   String findResult;   
    121.   
    122. //根据上边已经写好的query封装出一个查询计分器   
    123.   QueryScorer qs1 = new QueryScorer(q1);   
    124.   QueryScorer qs2 = new QueryScorer(q2);   
    125.   //设置高亮的模板,其实就是在关键字两边加一对html的格式标签,下面是最基本的加粗。   
    126.   Formatter formatter = new SimpleHTMLFormatter("<b>""</b>");   
    127.      
    128.   Highlighter highlighter1 = new Highlighter(formatter,qs1);   
    129.   Highlighter highlighter2 = new Highlighter(formatter,qs2);   
    130.   String text;   
    131.   
    132. //下面通过将上面根据关键字,过滤条件和权重排序等找出的结果集做一次循环,进行高亮,把高亮后得到的   
    133.   
    134. //一个字符串,封装如每个实体类中的一个额外字段,方便在页面输出。   
    135.   for(Product product:result){   
    136.    text = product.getProTitle() ;   
    137.    findResult = highlighter1.getBestFragment(analyzer,"pt", text);   
    138.    if(findResult==null){   
    139.     text = product.getProDescn() ;   
    140.     highlighter2.setTextFragmenter(new SimpleFragmenter(30));   
    141.     findResult = highlighter2.getBestFragment(analyzer,"pd", text);   
    142.    }   
    143.    product.setFindResult(findResult);   
    144.   }     
    145.   return result;   
    146.  }   
    147.   
    148. //下面的方法是用hibernate search的方法来创建索引   
    149.   
    150.  public void createIndexByHibernateSearch() {   
    151.   
    152.   long startTime = new Date().getTime();   
    153.   int BATCH_SIZE = 1000;   
    154.   FullTextSession s = Search.createFullTextSession(productDao.getSession());   
    155.   
    156.   // Transaction tr = s.beginTransaction();   
    157.   s.setFlushMode(FlushMode.MANUAL);   
    158.   s.setCacheMode(CacheMode.IGNORE);   
    159.   ScrollableResults results = s.createQuery("from Product").setFetchSize(BATCH_SIZE).scroll(ScrollMode.FORWARD_ONLY);   
    160.   int index = 0;   
    161.   while (results.next()) {   
    162.    index++;   
    163.    s.index(results.get(0)); // index each element   
    164.    if (index % BATCH_SIZE == 0) {   
    165.     // s.flushToIndexes(); //apply changes to indexes   
    166.     s.clear(); // clear since the queue is processed   
    167.    }   
    168.   }   
    169.   s.clear();   
    170.   long endTime = new Date().getTime();   
    171.   logger.warn("建立Product索引 , 这花费了" + (endTime - startTime) + " 毫秒来把文档增加到索引里面去!");   
    172.   // tr.commit();   
    173.   
    174.  }   
    175.   
    176. //下面的方法是用lucene的方式来创建索引文件,不过用这种方式创建索引后,也只能使用lucene的方式去进行搜索   
    177.   
    178.  @SuppressWarnings("deprecation")   
    179.  public void createIndexByLucene() {   
    180.   try {   
    181.    File fsDir = new File("E:\\indexes\\product");   
    182.    Analyzer analyzer = new IKAnalyzer();   
    183.   
    184.       
    185.    /* // 内存索引  
    186.       RAMDirectory ramDir = new RAMDirectory();  
    187.    IndexWriter ramWriter = new IndexWriter(ramDir, luceneAnalyzer,  
    188.      true, IndexWriter.MaxFieldLength.UNLIMITED);  
    189.    */  
    190.    IndexWriter fsWriter = new IndexWriter(   
    191.      FSDirectory.open(fsDir),   
    192.      analyzer,   
    193.      true,   
    194.      IndexWriter.MaxFieldLength.UNLIMITED   
    195.     );   
    196.    fsWriter.setMaxBufferedDocs(1000);   
    197.    fsWriter.setMergeFactor(1000);   
    198.   
    199.    List<Product> productList = find("from Product");   
    200.    int size = productList.size();   
    201.    long startTime = new Date().getTime();   
    202.    Document doc;   
    203.    for (Product product : productList) {   
    204.     doc = new Document();   
    205.     doc.add(new Field("pro_title", product.getProTitle(),Field.Store.YES, Field.Index.ANALYZED));   
    206.     doc.add(new Field("pro_descn", product.getProDescn(),Field.Store.YES, Field.Index.ANALYZED));   
    207.     if(product.getProTime()!=null)   
    208.     doc.add(new Field("pro_time",DateTools.dateToString( product.getProTime(), Resolution.DAY),Field.Store.YES, Field.Index.NOT_ANALYZED));   
    209.     fsWriter.addDocument(doc);   
    210.   
    211.     // 先缓存入内存索引,后写入文件索引   
    212.    /* ramWriter.addDocument(doc);  
    213.     int i = 1;  
    214.     i++;  
    215.     if (i % 100 == 0 || i == size) {  
    216.      logger.warn("i:" + i);  
    217.      ramWriter.close();  
    218.      fsWriter.addIndexesNoOptimize(new Directory[] { ramDir });  
    219.      ramWriter = new IndexWriter(ramDir, new StandardAnalyzer(),  
    220.        true, IndexWriter.MaxFieldLength.UNLIMITED);  
    221.     }*/  
    222.   
    223.    }   
    224.    // 自动优化合并索引文件   
    225.    fsWriter.optimize();   
    226.    fsWriter.close();   
    227.   
    228.    long endTime = new Date().getTime();   
    229.    System.out.println("一共" + size + ",这花费了" + (endTime - startTime)   
    230.      + " 毫秒来把文档增加到索引里面去!");   
    231.       
    232.   
    233.   } catch (Exception e) {   
    234.    e.printStackTrace();   
    235.   }   
    236.  }   
    237.     
    238.  public void SearchByLucene(){   
    239.   createIndexByLucene();   
    240.   File fsDir = new File("E:\\luceneIndexes\\product");   
    241.   Analyzer analyzer = new IKAnalyzer();   
    242.   try{   
    243.    // 索引查询   
    244.    IndexReader reader = IndexReader.open(FSDirectory.open(fsDir), true); // only searching, so read-only=true   
    245.    IndexSearcher isearcher = new IndexSearcher(reader);   
    246.       
    247.    BooleanQuery booleanQuery = new BooleanQuery();   
    248.    QueryParser parser;   
    249.    Query query;   
    250.       
    251.    parser = new QueryParser(Version.LUCENE_CURRENT,"pro_title",analyzer);   
    252.    query = parser.parse("大灯");// 检索词   
    253.    query.setBoost(1.5f);   
    254.    booleanQuery.add(query, Occur.SHOULD);   
    255.       
    256.    parser = new QueryParser(Version.LUCENE_CURRENT,"pro_descn",analyzer);      
    257.    query = parser.parse("大灯");// 检索词   
    258.    query.setBoost(1.0f);   
    259.    booleanQuery.add(query, Occur.SHOULD);   
    260.       
    261.    BooleanQuery filterBooleanQuery = new BooleanQuery();   
    262.    TermRangeQuery rangeQuery = new TermRangeQuery("pro_time","20090101","20091101",true,true);   
    263.    filterBooleanQuery.add(rangeQuery, BooleanClause.Occur.MUST);   
    264.       
    265.    // 将booleanQuery封装到Filter中   
    266.    Filter filter = new CachingWrapperFilter(new QueryWrapperFilter(filterBooleanQuery));   
    267.       
    268.    TopScoreDocCollector collector = TopScoreDocCollector.create(100,true);       
    269.       
    270.    isearcher.search(booleanQuery,filter,collector);   
    271.       
    272.    ScoreDoc[] hits = collector.topDocs(0,100).scoreDocs;   
    273.    QueryScorer qs = new QueryScorer(new TermQuery(new Term("pro_title","大灯")));   
    274.       
    275.    for(ScoreDoc h:hits){   
    276.     Document d = isearcher.doc(h.doc);   
    277.     String text = d.get("pro_title") ;   
    278.     Formatter formatter = new SimpleHTMLFormatter("<b>""</b>");    
    279.        
    280.     Highlighter hl = new Highlighter(formatter,qs);   
    281.        
    282.     System.out.println(hl.getBestFragment(analyzer,"pro_title", text));   
    283.     //System.out.println("doc:"+h.doc+"  \tscore:"+h.score+"      \t"+d.get("pro_title"));   
    284.    }   
    285.    System.out.println("命中:" + hits.length);   
    286.    isearcher.close();   
    287.       
    288.   }catch(Exception e){   
    289.    e.printStackTrace();   
    290.   }   
    291.      
    292.  }   
    293.   
    294.  // 查看分词效果   
    295.  @SuppressWarnings("deprecation")   
    296.  public static void showAnalyzerResult(Analyzer analyzer, String s)   
    297.    throws Exception {   
    298.   StringReader reader = new StringReader(s);   
    299.   TokenStream ts = analyzer.tokenStream(s, reader);   
    300.   Token t = ts.next();   
    301.   while (t != null) {   
    302.    System.out.print(t.termText() + "   ");   
    303.    t = ts.next();   
    304.   }   
    305.   System.out.println();   
    306.  }   
    307.   
    308.  public static void main(String[] args) {   
    309.   ApplicationContext ctx = new ClassPathXmlApplicationContext("spring/applicationContext.xml");   
    310.   ProductService service = (ProductService) ctx.getBean("productService");   
    311.   
    312.   service.SearchByLucene();   
    313.   
    314.  }   
    315. }  
  • 相关阅读:
    Android Dalvik 虚拟机
    我在北京找工作(二):java实现算法<1> 冒泡排序+直接选择排序
    如何用java比较两个时间或日期的大小
    [安卓破解]听网页浏览器,无需注册即可语音朗读
    (step8.2.4)hdu 1846(Brave Game——巴什博奕)
    Oracle Database 12c Release 1 Installation On Oracle Linux 6.4 x86_64
    HDU2084:数塔(DP)
    MySQL MVCC(多版本并发控制)
    POJ
    网易前端微专业,JavaScript程序设计基础篇:数组
  • 原文地址:https://www.cnblogs.com/yangy608/p/1872432.html
Copyright © 2020-2023  润新知