`
xiangxingchina
  • 浏览: 506774 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用 Compass 第三方框架维护索引库数据

阅读更多

使用 Compass 第三方框架维护索引库数据

 

1. Compass 基于 Lucene 的关系,就类似 Hibernate JDBC 的关系。但是目前 Compass 应用并不广泛,大多都是直接使用 Lucene 。咱为了效率,不差 Compass 再封装的这点功夫。但这个框架确实很精彩 ~

 

2. 由于 Compass 的 API 风格和 Hibernate 的风格很像,先看看 Hibernate API:

      

  1. Configuration config =  new  Configuration().configure();  
  2. SessionFactory sessionFactory = config.buildSessionFactory();  
  3. Session session = null ;  
  4. Transaction tx = null ;  
  5. try  {  
  6.     session = sessionFactory.openSession();  
  7.     tx = session.beginTransaction();              
  8.     // 更新操作   
  9.     tx.commit();          
  10. catch  (Exception e) {  
  11.     if  (tx !=  null ) {  
  12.               tx.rollback();  
  13.     }  
  14.     throw  e;  
  15. finally  {  
  16.     if  (session !=  null ) {  
  17.           session.close();  
  18.     }  
  19. }  
 

 

3. Compass API

      

  1. CompassConfiguration cfg =  new  CompassConfiguration().configure();  
  2. Compass compassSessionFactory = cfg.buildCompass();  
  3. CompassSession session = null ;  
  4. CompassTransaction tx = null ;  
  5. try  {  
  6.     session = compassSessionFactory.openSession();  
  7.     tx = session.beginTransaction();              
  8.     // 更新操作   
  9.     tx.commit();          
  10. catch  (Exception e) {  
  11.     if (tx !=  null ) {  
  12.           tx.rollback();  
  13.     }  
  14.     throw  e;  
  15. finally  {  
  16.     if  (session !=  null ) {  
  17.           session.close();  
  18.     }  
  19. }  
 

 

4. 比较看来, Compass API 简直和 Hibernate 如出一辙。具体,下面写一个 HelloWorld

       ** 导入 jar 包:

              dist\commons-logging.jar

              dist\compass-2.2.0.jar

              dist\lucene\*.jar

          2.2 Compass 最新的版本,但是使用的 lucene 版本却是 2.4

          lucene2.4 现在 3.0 版本的比起来不但 API 有些较大的变化,效率上 3.0 也更好。但是此处不能将 Lucene 的版本换成 3.0 。那样 Compass 底层就没办法工作了。

      

       ** src 目录下新建 XML 文件 compass.cfg.xml

            

  1. <? xml   version = "1.0"   encoding = "UTF-8" ?>   
  2. < compass-core-config   xmlns = "http://www.compass-project.org/schema/core-config"   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"   
  3.     xsi:schemaLocation ="http://www.compass-project.org/schema/core-config  
  4.            http://www.compass-project.org/schema/compass-core-config-2.2.xsd">   
  5.     < compass   name = "default" >   
  6.         <!-- 1,连接信息 -->   
  7.         < connection >   
  8.             <!-- 索引库创建的位置 -->   
  9.             < file   path = "./indexDir/"   />   
  10.         </ connection >   
  11.         <!-- 2,声明映射信息 -->   
  12.         < mappings />   
  13.         <!-- 3,其他配置 -->   
  14.         < settings />   
  15.     </ compass >   
  16. </ compass-core-config >   
 

      

       ** HelloWorld

              domain : Article

              

  1. /**  
  2.  * 文章实体  
  3.  */   
  4. @Searchable     // 将实体纳入 Compass 索引库 -- 实体 映射管理中   
  5. public   class  Article {  
  6.     @SearchableId   
  7.     private  Long id;  
  8.     @SearchableProperty (store = Store.YES, index = Index.ANALYZED)    // 意思参见 Lucene-HelloWorld   
  9.     private  String title;  
  10.     @SearchableProperty (store = Store.YES, index = Index.ANALYZED)  
  11.     private  String content;  
  12.     public  Long getId() {  
  13.         return  id;  
  14.     }  
  15.     public   void  setId(Long id) {  
  16.         this .id = id;  
  17.     }  
  18.     public  String getTitle() {  
  19.         return  title;  
  20.     }  
  21.     public   void  setTitle(String title) {  
  22.         this .title = title;  
  23.     }  
  24.     public  String getContent() {  
  25.         return  content;  
  26.     }  
  27.     public   void  setContent(String content) {  
  28.         this .content = content;  
  29.     }  
  30. }  
 

            

             ** compass.cfg.xml 中映射实体类:

             <mappings>

                     <class name="compass.helloworld.domain.Article" />

              </mappings>

            

             ** HelloWorld

               

  1. public   class  HelloWorld {  
  2.     // 创建索引(模拟发帖的操作)   
  3.     @Test   
  4.     public   void  createIndex()  throws  Exception {  
  5.         // 模拟一条文章数据   
  6.         Article article = new  Article();  
  7.         article.setId(1L);  
  8.         article.setTitle("wjh上天山" );  
  9.         article.setContent("据悉,wjh已于昨日抵达天山。高歌一曲HelloWorld" );  
  10.         // 保存到索引库中   
  11.         CompassSession session = CompassUtils.getCompassSessionFactory().openSession();  
  12.         CompassTransaction tx = session.beginTransaction();  
  13.         session.create(article); // 创建索引,并非 sesion.save(),save() 方法在 Compass 中表示 “保存或更新”   
  14.         tx.commit();  
  15.         session.close();  
  16.     }  
  17.     // 搜索(模拟搜索文章的操作)   
  18.     @Test   
  19.     public   void  search()  throws  Exception {  
  20.         // 搜索条件   
  21.         String queryString = "HelloWorld" ;  
  22.         CompassSession session = CompassUtils.getCompassSessionFactory().openSession();  
  23.         CompassTransaction tx = session.beginTransaction();  
  24.         CompassHits hits = session.find(queryString);  
  25.         int  count = hits.length();  // 符合条件的总结果数   
  26.         // 处理结果   
  27.         List<Article> list = new  ArrayList<Article>();  
  28.         for  ( int  i =  0 ; i < hits.length(); i++) {  
  29.             Article article = (Article) hits.data(i); // 真正的取出数据   
  30.             list.add(article);  
  31.         }  
  32.         tx.commit();  
  33.         session.close();  
  34.         // 显示结果   
  35.         System.out.println("符合条件的总结果数:"  + count);  
  36.         for  (Article article : list) {  
  37.             System.out.println("-------> id = "  + article.getId());  
  38.             System.out.println("title   = "  + article.getTitle());  
  39.             System.out.println("content = "  + article.getContent());  
  40.         }  
  41.     }  
  42. }  
 

 

 

5. 使用 compass 维护索引库

       ** CompassUtils

        

  1. public   class  CompassUtils {  
  2.     // Compass对象只需要一个就可以了   
  3.     private   static  Compass compassSessionFactory;  
  4.     static  {  
  5.         CompassConfiguration cfg = new  CompassConfiguration().configure();  
  6.         compassSessionFactory = cfg.buildCompass();  
  7.     }  
  8.     /**  
  9.      * 获取Compass对象  
  10.      *   
  11.      * @return  
  12.      */   
  13.     public   static  Compass getCompassSessionFactory() {  
  14.         return  compassSessionFactory;  
  15.     }  
  16. }  
 

      

       ** QueryResult

          

  1. /**  
  2.  * 分页搜索结果集   
  3.  */   
  4. public   class  QueryResult {  
  5.     /* 总记录数 */   
  6.     private   int  count;   
  7.     /* 一页的数据 */   
  8.     private  List list;   
  9.     public  QueryResult( int  count, List list) {  
  10.         this .count = count;  
  11.         this .list = list;  
  12.     }  
  13.     public   int  getCount() {  
  14.         return  count;  
  15.     }  
  16.     public   void  setCount( int  count) {  
  17.         this .count = count;  
  18.     }  
  19.     public  List getList() {  
  20.         return  list;  
  21.     }  
  22.     public   void  setList(List list) {  
  23.         this .list = list;  
  24.     }  
  25. }  
 

      ** DAO

          

  1. /**  
  2.  * DAO  
  3.  */   
  4. public   class  ArticleIndexDao {  
  5.     /**  
  6.      * 保存到索引库(创建索引)  
  7.      *   
  8.      * @param article  
  9.      */   
  10.     public   void  save(Article article) {  
  11.         CompassSession session = CompassUtils.getCompassSessionFactory().openSession();  
  12.         CompassTransaction tx = null ;  
  13.         try  {  
  14.             tx = session.beginTransaction();  
  15.             session.create(article);// 创建索引   
  16.             tx.commit();  
  17.         } catch  (Exception e) {  
  18.             tx.rollback();  
  19.             throw   new  RuntimeException(e);  
  20.         } finally  {  
  21.             session.close();  
  22.         }  
  23.     }  
  24.     /**  
  25.      * 删除索引  
  26.      *   
  27.      * @param id  
  28.      */   
  29.     public   void  delete(Long id) {  
  30.         CompassSession session = CompassUtils.getCompassSessionFactory().openSession();  
  31.         CompassTransaction tx = null ;  
  32.         try  {  
  33.             tx = session.beginTransaction();  
  34.             session.delete(Article.class , id);  // 删除索引   
  35.             tx.commit();  
  36.         } catch  (Exception e) {  
  37.             tx.rollback();  
  38.             throw   new  RuntimeException(e);  
  39.         } finally  {  
  40.             session.close();  
  41.         }  
  42.     }  
  43.     /**  
  44.      * 更新索引  
  45.      *   
  46.      * @param article  
  47.      */   
  48.     public   void  update(Article article) {  
  49.         CompassSession session = CompassUtils.getCompassSessionFactory().openSession();  
  50.         CompassTransaction tx = null ;  
  51.         try  {  
  52.             tx = session.beginTransaction();  
  53.             session.save(article); // 更新索引(创建或更新索引)   
  54.             tx.commit();  
  55.         } catch  (Exception e) {  
  56.             tx.rollback();  
  57.             throw   new  RuntimeException(e);  
  58.         } finally  {  
  59.             session.close();  
  60.         }  
  61.     }  
  62.     /**  
  63.      * 搜索  
  64.      *   
  65.      * @param queryString  
  66.      *            搜索条件  
  67.      * @param firstResult  
  68.      * @param maxResults  
  69.      * @return 一段数据 + 总记录数  
  70.      */   
  71.     public  QueryResult search(String queryString,  int  firstResult,  int  maxResults) {  
  72.         CompassSession session = CompassUtils.getCompassSessionFactory().openSession();  
  73.         CompassTransaction tx = null ;  
  74.         try  {  
  75.             tx = session.beginTransaction();  
  76.             // 查询   
  77.             CompassHits hits = session.find(queryString);  
  78.             int  count = hits.length();  // 总结果数   
  79.             // 处理数据列表   
  80.             List<Article> list = new  ArrayList<Article>();  
  81.             int  endIndex = Math.min(firstResult + maxResults, hits.length());  
  82.             for  ( int  i = firstResult; i < endIndex; i++) {  // 只取一段数据   
  83.                 Article article = (Article) hits.data(i);  
  84.                 // ===========================================   
  85.                 // 进行高亮操作。返回高亮后的一段文本,如果高亮的属性中没有搜索的关键词,则返回null   
  86.                 String text = hits.highlighter(i).fragment("content" );  
  87.                 if  (text !=  null ) {  
  88.                     article.setContent(text); // 替换为高亮后的摘要   
  89.                 }  
  90.                 // ===========================================   
  91.                 list.add(article);  
  92.             }  
  93.             tx.commit();  
  94.             // 返回结果   
  95.             return   new  QueryResult(count, list);  
  96.         } catch  (Exception e) {  
  97.             tx.rollback();  
  98.             throw   new  RuntimeException(e);  
  99.         } finally  {  
  100.             session.close();  
  101.         }  
  102.     }  
  103. }  
  104. /**  
  105.  * 由于在编写过程中,常常需要编写大量模板代码。  
  106.  * 于是 compass 也提供了一个封装后的模板 CompassTemplate,使用起来代码更简洁  
  107.  */   
  108. public   class  ArticleIndexDao2 {  
  109.     /**  
  110.      * 保存到索引库(创建索引)  
  111.      *   
  112.      * @param article  
  113.      */   
  114.     public   void  save(Article article) {  
  115.         CompassTemplate compassTemplate = new  CompassTemplate(CompassUtils.getCompassSessionFactory());  
  116.         compassTemplate.create(article);  
  117.     }  
  118.     /**  
  119.      * 删除索引  
  120.      *   
  121.      * @param id  
  122.      */   
  123.     public   void  delete(Long id) {  
  124.         CompassTemplate compassTemplate = new  CompassTemplate(CompassUtils.getCompassSessionFactory());  
  125.         compassTemplate.delete(Article.class , id);  
  126.     }  
  127.     /**  
  128.      * 更新索引  
  129.      *   
  130.      * @param article  
  131.      */   
  132.     public   void  update(Article article) {  
  133.         CompassTemplate compassTemplate = new  CompassTemplate(CompassUtils.getCompassSessionFactory());  
  134.         compassTemplate.save(article);  
  135.     }  
  136.     /**  
  137.      * 搜索  
  138.      *   
  139.      * @param queryString  
  140.      *            搜索条件  
  141.      * @param firstResult  
  142.      * @param maxResults  
  143.      * @return 一段数据 + 总记录数  
  144.      */   
  145.     public  QueryResult search( final  String queryString,  final   int  firstResult,  final   int  maxResults) {  
  146.         CompassTemplate compassTemplate = new  CompassTemplate(CompassUtils.getCompassSessionFactory());  
  147.         return  compassTemplate.execute( new  CompassCallback<QueryResult>() {  
  148.             public  QueryResult doInCompass(CompassSession session)  throws  CompassException {  
  149.                 // 查询   
  150.                 CompassHits hits = session.find(queryString);  
  151.                 int  count = hits.length();  // 总结果数   
  152.                 // 处理数据列表   
  153.                 List<Article> list = new  ArrayList<Article>();  
  154.                 int  endIndex = Math.min(firstResult + maxResults, hits.length());  
  155.                 for  ( int  i = firstResult; i < endIndex; i++) {  // 只取一段数据   
  156.                     Article article = (Article) hits.data(i);  
  157.                     list.add(article);  
  158.                 }  
  159.                 // 返回结果   
  160.                 return   new  QueryResult(count, list);  
  161.             }  
  162.         });  
  163.     }  
  164. }  
 

       

 

6. 对搜索关键字高亮显示

       compass.cfg.xml <settings> 节点中加入配置:

              <settings>

                     <!-- 高亮器:摘要大小 -->

                     <setting name="compass.engine.highlighter.default.fragmenter.simple.size" value="100" />

                     <!-- 高亮器:前缀 <font color="#FF0000"> -->

                     <setting name="compass.engine.highlighter.default.formatter.simple.pre" value="&lt;font color='red'&gt;" />

                     <!-- 高亮器:后缀 </font> -->

                     <setting name="compass.engine.highlighter.default.formatter.simple.post" value="&lt;/font &gt;"/>

              </settings>

 

7. 自定义分词器:

       <!-- 这里使用的是 " 极易分词 " 。要注意的时候,分词器必须要是支持 Lucene2.4 的版本   -->

       <setting name="compass.engine.analyzer.default.type" value="jeasy.analysis.MMAnalyzer" />

 

8. 排序

   ** 影响搜索结果的 “相关度” 排序。 Lucene 默认是通过对匹配结果按照 " 关键字出现的次数 " " 关键词出现的密集程度 " 等,用某种算法形成 “相关度得分”实现排序,得分越高排序越靠前。

      程序员可以人为影响搜索结果的相关度。

      例如本例中,只需要为实体类 Article 增加一个属性,并加上对应注解:

          @SearchableBoostProperty

       private float boostValue = 1F;

       属性名称随意,但是一定要加上 "@SearchableBoostProperty" 注解,并设置默认值为 1 。设置了这个属性之后,每次保存这个实体时,若不改变这个属性的值,每次搜索出实体数据时,它的相关度都会被乘以 1 。也就是不变。

       但是若将这个值设置为 2 的话,搜索时,这个实体对象对应的数据的相关度将乘以 2 。本来它的相关度可能仅仅为 0.4 ,但是乘以 2 后,就成了 0.8 了。它在搜索结果中的排名将大大靠前。例如:   

              Article article = new Article();

              article.setId(27L);

              article.setTitle("Title");

              article.setContent("content content content");

<span lang

分享到:
评论

相关推荐

    JAVA上百实例源码以及开源项目源代码

    2个目标文件,FTP的目标是:(1)提高文件的共享性(计算机程序和/或数据),(2)鼓励间接地(通过程序)使用远程计算机,(3)保护用户因主机之间的文件存储系统导致的变化,(4)为了可靠和高效地传输,虽然用户...

    Java资源包01

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包8

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    JAVA上百实例源码以及开源项目

    2个目标文件,FTP的目标是:(1)提高文件的共享性(计算机程序和/或数据),(2)鼓励间接地(通过程序)使用远程计算机,(3)保护用户因主机之间的文件存储系统导致的变化,(4)为了可靠和高效地传输,虽然用户...

    java开源包1

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包11

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包2

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包3

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包6

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包5

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包10

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包4

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包7

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包9

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

    java开源包101

    同时,任何第三方都可以使用OAUTH认证服务,任 何服务提供商都可以实现自身的OAUTH认证服务,因而OAUTH是开放的。业界提供了OAUTH的多种实现如PHP,JavaScript,Java,Ruby等各种语言开发包,大大节约了程序员的时间...

Global site tag (gtag.js) - Google Analytics