zoukankan      html  css  js  c++  java
  • 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. }  
  • 相关阅读:
    数据库字段太多,批量快速建立实体类方法(适合大量字段建立实体类)
    SQL service 中的 ”输入SQL命令窗口“ 打开了 “属性界面” 回到 ”输入SQL命令窗口“
    计算机软件编程英语词汇集锦
    编程常用英语词汇
    svn上传和下载项目
    当启动tomcat时出现tomcat setting should be set in tomcat preference page
    Implicit super constructor Object() is undefined for default constructor. Must define an explicit constructor
    eclipse中选中一个单词 其他相同的也被选中 怎么设置
    Spring Boot的@SpringBootApplication无法引入的问题
    最全的SpringCloud视频教程
  • 原文地址:https://www.cnblogs.com/yangy608/p/1872432.html
Copyright © 2011-2022 走看看