全文检索 Compass 配置使用

我们在使用Lucene管理Document时,难免有些复杂,并且在做增量索引时会比较繁琐,因此需要用到Compass。 Compass对Lucene的使用就如同Hibernate和对Jdbc的使用,Compass的工作流程如下:


本文使用Compass2.2版本,所需jar如下:


使用compass的步骤和使用hibernate的步骤基本一致:

使用hibernate时步骤一般为:

1.建立实体类,也就是Entity,如Student,Teacher,这些实体类。

2.配置实体类到数据库的映射。配置方法一般有两种:

  (1)使用xml。如(Student.hbm.xml)

  (2)使用annotation 注解 @Entity ,@Id等

    Hiberante中要求每个实体都要有个标识(Id),compass中也这么要求。

3.使用hibernate的API操作实体

Configuration cfg = new Configuration().configure(); //默认加载hibernate.cfg.xml

SessionFactory sessionFactory =cfg.buildSessionFactory(); //全局唯一

Session session = sessionFactory.openSession();

session.beginTransaction(); //开启事务

session.save(xxx);//保存

session.delete(xxx);//删除

session.get(xxx.class,id)//获得对象

........//其他操作

session.getTransaction().commit(); //提交事务

session.close(); //关闭session

 

而使用compass 和 hibernate的步骤几乎是一样的:

1.建立实体类,如Student,Teacher等实体类。

2.配置实体类到索引库的映射。

以Student类为例:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @Entity //在hibernate中,使用@Entity将Student类映射到数据库的student表  
  2. @Searchable(alias="product"//在compass中,使用@Searchable将Student映射到索引库中的 product 文档(Document),alias用来指定该实体类对应的document的名称,不设置alias则默认使用小写的类名。如果searchable的root属性设为false,则该类不会被创建为一个单独的document。一般该类作为另外一个类的组件时,才设置该属性为false。这事要想通过该类的属性搜索该类就会报错。  
  3. public class Student{  
  4.     //hibernate 和 compass中都规定,实体必须有一个标识字段  
  5.     private int id;  
  6.     private String name;  
  7.     private String fond;  
  8.     private Teacher teacher;  
  9.     @Id //hiberante中,使用@Id来将一个字段映射为实体的标识ID  
  10.     @SearchableId //compass中,则使用@SearchableId将一个字段映射为实体的标识ID  
  11.     public int getId(){  
  12.         return id;  
  13.     }  
  14.     /* 
  15.      * 在hibernate中,对应属性如果不设置的话,则默认的映射为对应名称的字段; 
  16.     在compass中实体类的属性则需要使用@SearchableProperty来设置,设置用来检索的属性,以及属性值是否被索引、是否被存储,以及相关度boost 
  17.     @SearchableProperty中的name属性用来指定filed的名称; 
  18.     index指定是否建立索引, 
  19.         Index.ANALYZE表示建立索引并进行分词(为默认值),即建立索引时会对该filed进行分词,并在检索的时候可以通过该filed进行搜索; 
  20.         Index.NOT_ANALYZED 表示会对该字段建立索引,但不会进行分词; 
  21.         Index.NO 表示不会对该字段建立索引,当然也不会进行分词了; 
  22.     store表示该字段是否要被存储到索引库中,默认值为store=Store.YES; 
  23.     指定Index.NOT_ANALYZED并且指定Store.YES,则是为了搜索到实体时,将该filed值加载出来; 
  24.     boost表示相关度,相关度是一个float型的值,值越大,通过字段匹配的结果排序越靠前; 
  25.     */  
  26.     @SearchableProperty(name="name",index=Index.ANALYZED,store=Store.YES,boost=3f)  
  27.     public String getName(){  
  28.         return name;  
  29.     }  
  30.     public String getFond(){  
  31.         return fond;  
  32.     }     
  33.     /* 
  34.     @SearchableComponent复合类型,该类型的对象Teacher被看做是当前类Student的一部分,一个组件,创建document时,复合类型的属性会和student的属性放在同一个document中。 
  35.     当进行查询时,会先查询主类的数据元字段,也会查询组件类如Teacher类中的字段,因为在创建document时,teacher的数据元字段作为student的一部分放到了document中。 
  36.     */  
  37.     @SearchableComponent  
  38.     public Teacher getTeacher(){  
  39.         return teacher;  
  40.     }  
  41.     public void setTeacher(Teacher teacher){  
  42.         this.teacher = teacher;  
  43.     }  
  44. }  

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //把root属性设为false,表示该类不是一个独立的实体,它只是其他类(Student)的一部分  
  2. @Searchable(root=false)  
  3. public class Teacher {  
  4.     //此时该类的id就不能做为索引库中的标识了,因为该类被当做是Student的的一部分,而Student中已经有标识了。  
  5.     @SearchableProperty(name="tid",index=Index.NO,store=Store.YES)  
  6.     private int id;  
  7.     /*应为在创建索引时,该name对应的索引字段为name,而在Student中name对应的索引字段也为name,会造成冲突, 
  8.      * 所以需要将复合类型中与主类属性名字相同的该为其他的的名称,以免冲突。 
  9.     */  
  10.     @SearchableProperty(name="tname",index=Index.ANALYZED,store=Store.YES)  
  11.     private String name;  
  12.     @SearchableProperty(name="tage",index=Index.NO,store=Store.YES)  
  13.     private int age;  
  14.     @SearchableProperty(name="tfond",index=Index.ANALYZED,store=Store.YES)  
  15.     private String fond;  
  16.     //也就是说,查询到Teacher类的某个实体时,可以根据该实体加载出来其对应的student对象。  
  17.     @SearchableReference  
  18.     private Student student;  
  19.     //…………………………省略get/set方法   
  20. }  

3.使用Compass中的API对实体进行操作:

    Compasscompass = new CompassConfiguration().configure().bulidCompass();

    /*compass 相当于 hibernatesessionfactory

上面的configure()方法会自动去classpathcompass.cfg.xml配置文件这个方法和hibernate中的configure()方法很相似,hibernate中的该方法用来加载hibernate.cfg.xml.

     如果要制定其他名称的配置文件可以使用configure(xxx).

CompassSession相当于hibernate中的Session

*/

CompassSession compassSession = compass.openSession();

compassSession.beginTransaction(); //CompassTransaction相当于 Hiberante中的Transaction,compss中也是有事务支持的和数据库很相似也有事务回滚tx.rollback()

compassSession.create(entity)/.create(entity);//保存到索引文件

compassSession.delete(entity);//将实体从索引库中删除

compassSession.commit();

compassSession.close();

下面是测试时使用compass进行保存,查询等操作的关键代码:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @Searchable //告诉compass,将该类映射到Lucene的Document    
  2. public class Product {    
  3.          private Integer id;    
  4.          private String name;    
  5.          private String content;    
  6.          private Float price;    
  7.          private String note;    
  8.          private Integer position;    
  9.          private Integer typeid;    
  10.              
  11.          public Product(){}    
  12.              
  13.          public Product(Integer id) {    
  14.                    this.id = id;    
  15.          }    
  16.      
  17.          public Product(Integer id, String name, String content, Float price,String note,Integer typeid,Integer position) {    
  18.                    this.id = id;    
  19.                    this.name = name;    
  20.                    this.content = content;    
  21.                    this.price = price;    
  22.                    this.note = note;    
  23.                    this.typeid = typeid;    
  24.                    this.position = position;    
  25.          }    
  26.              
  27.          @SearchableId //compass要求每个搜索实体类都要具有一个标识属性,这点和Hibernate相似    
  28.          public Integer getId() {    
  29.                    return id;    
  30.          }    
  31.          public void setId(Integer id) {    
  32.                    this.id = id;    
  33.          }    
  34.          @SearchableProperty(index=Index.NOT_ANALYZED, store=Store.YES)//store的默认值为Store.YES    
  35.          public Integer getTypeid() {    
  36.                    return typeid;    
  37.          }    
  38.      
  39.          public void setTypeid(Integer typeid) {    
  40.                    this.typeid = typeid;    
  41.          }    
  42.      
  43.          @SearchableProperty(boost=2)//boost的默认值为1,用于设置属性在索引中的重要性    
  44.          public String getName() {    
  45.                    return name;    
  46.          }    
  47.          public void setName(String name) {    
  48.                    this.name = name;    
  49.          }    
  50.      
  51.          @SearchableProperty    
  52.          public String getContent() {    
  53.                    return content;    
  54.          }    
  55.          public void setContent(String content) {    
  56.                    this.content = content;    
  57.          }    
  58.          //价格不需要进行搜索,但需要存储,如果没有存储,就需要从数据库中获取价格了    
  59.          @SearchableProperty(index=Index.NO)//store的默认值为Store.YES    
  60.          public Float getPrice() {    
  61.                    return price;    
  62.          }    
  63.          public void setPrice(Float price) {    
  64.                    this.price = price;    
  65.          }    
  66.          @SearchableProperty(store=Store.YES)    
  67.          public String getNote() {    
  68.                    return note;    
  69.          }    
  70.      
  71.          public void setNote(String note) {    
  72.                    this.note = note;    
  73.          }    
  74.          @SearchableProperty(index=Index.NOT_ANALYZED, store=Store.YES)//store的默认值为Store.YES    
  75.          public Integer getPosition() {    
  76.                    return position;    
  77.          }    
  78.          public void setPosition(Integer position) {    
  79.                    this.position = position;    
  80.          }          
  81. }    


 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class ProductSearchBean {    
  2.          private Compass compass = null;//-->SessionFactory    
  3.              
  4.          public ProductSearchBean(){    
  5.                     try {    
  6.                              //编程式配置    
  7.                             compass = new CompassAnnotationsConfiguration()    
  8.                             .setSetting(CompassEnvironment.CONNECTION, "file://indexfile")    
  9.                             //.setSetting(CompassEnvironment.CONNECTION, "ram://index")//在内存中建立索引    
  10.                             .setSetting("compass.engine.analyzer.default.type""net.paoding.analysis.analyzer.PaodingAnalyzer")  
  11.                             .setSetting("compass.engine.highlighter.default.formatter.simple.pre","<font color='red'>")    
  12.                             .setSetting("compass.engine.highlighter.default.formatter.simple.post","</font>")    
  13.                               
  14.                             .addScan("lxq.compass").buildCompass();    
  15.                    } catch (Exception e) {    
  16.                             e.printStackTrace();    
  17.                    }    
  18.          }    
  19.             
  20.          public void buildIndex(){    
  21.                    CompassSession session = null;    
  22.                    CompassTransaction tx = null;    
  23.                    try {    
  24.                             session = compass.openSession();    
  25.                             tx = session.beginTransaction();          
  26.                             Product p1 = new Product(12,"c瑜珈球","非常好的瑜珈球",12f, "www"212);    
  27.                             session.create(p1);    
  28.                             Product p2 = new Product(35,"b瑜珈球","天花板瑜珈球,good",42f, "mmm",2,9);    
  29.                             session.create(p2);    
  30.                             Product p3 = new Product(8,"a蓝球瑜珈球","蓝球小子",125f, "ppp",5,8);                               
  31.                             session.create(p3);    
  32.                             tx.commit();    
  33.                    } catch (CompassException e) {    
  34.                             e.printStackTrace();    
  35.                             tx.rollback();    
  36.                    }finally{    
  37.                             if(session!=null && !session.isClosed()) session.close();    
  38.                    }    
  39.          }    
  40.      
  41.          public void deleteIndex(Product product) {    
  42.                    CompassSession session = null;    
  43.                    CompassTransaction tx = null;    
  44.                    try {    
  45.                             session = compass.openSession();    
  46.                             tx = session.beginTransaction();    
  47.                        session.delete(product);    
  48.                        tx.commit();    
  49.                    } catch (CompassException e) {    
  50.                             e.printStackTrace();    
  51.                             tx.rollback();    
  52.                    }finally{    
  53.                             if(session!=null && !session.isClosed()) session.close();    
  54.                    }    
  55.          }    
  56.      
  57.          public void updateIndex(Product product) {    
  58.                    CompassSession session = null;    
  59.                    CompassTransaction tx = null;    
  60.                    try {    
  61.                       session = compass.openSession();    
  62.                       tx = session.beginTransaction();    
  63.                       session.delete(product);    
  64.                       session.save(product);    
  65.                       tx.commit();    
  66.                    } catch (CompassException e) {    
  67.                             e.printStackTrace();    
  68.                             tx.rollback();    
  69.                    }finally{    
  70.                             if(session!=null && !session.isClosed()) session.close();    
  71.                    }    
  72.          }    
  73.      
  74.          public void destroy(){    
  75.                    compass.close();    
  76.          }    
  77.              
  78.          public QueryResult<Product> search(String keyword, int firstIndex, int maxResult) {    
  79.                    QueryResult<Product> qr = new QueryResult<Product>();    
  80.                    CompassSession session = null;    
  81.                    CompassTransaction tx = null;    
  82.                    try {    
  83.                              session = compass.openSession();    
  84.                              tx = session.beginTransaction();    
  85.                             //对所有索引Field进行搜索,你也可以指定对某个Field搜索,如:"name:jack",如果想指定多个字段可以用空格和"+"隔开如"name:jack +content:xxx"    
  86.                              CompassHits hits = session.find(keyword);   
  87.                              List<Product> products = new ArrayList<Product>();    
  88.                              int length = firstIndex+ maxResult;    
  89.                              if(length>hits.length()) length = hits.length();                              
  90.                              for(int i=firstIndex; i<length; i++){    
  91.                                       Product product = (Product)hits.data(i);    
  92.                                       product.setContent(hits.highlighter(i).fragment("content"));    
  93.                     
  94.                              }    
  95.                              qr.setResultlist(products);    
  96.                              qr.setTotalrecord(hits.length());    
  97.                              hits.close();    
  98.                    } catch (CompassException e) {    
  99.                             e.printStackTrace();    
  100.                             tx.rollback();    
  101.                    }finally{    
  102.                             if(session!=null && !session.isClosed()) session.close();    
  103.                    }    
  104.                    return qr;    
  105.          }    
  106.              
  107.          public QueryResult<Product> search(String keyword, Integer typeid, int firstIndex, int maxResult) {    
  108.                    QueryResult<Product> qr = new QueryResult<Product>();    
  109.                    CompassSession session = null;    
  110.                    CompassTransaction tx = null;    
  111.                    try {    
  112.                              session = compass.openSession();    
  113.                              tx = session.beginTransaction();    
  114.                              //查询指定类别的匹配记录,并按position降序排序    
  115.                              CompassQueryBuilder queryBuilder = session.queryBuilder();    
  116.                              CompassHits hits = queryBuilder.bool()    
  117.                                     .addMust(queryBuilder.spanEq("typeid", typeid))    
  118.                                     .addMust(queryBuilder.queryString(keyword).toQuery())    
  119.                                   .toQuery().addSort("position", SortPropertyType.FLOAT, SortDirection.REVERSE)    
  120.                                   .hits();//sql: typeid=1 and (xxxx like ?) order by positoin desc    
  121.                                  
  122.                              List<Product> products = new ArrayList<Product>();    
  123.                              int length = firstIndex+ maxResult;    
  124.                              if(length>hits.length()) length = hits.length();                              
  125.                              for(int i=firstIndex; i<length; i++){    
  126. //在hits调用data(i)方法时,才会真正的返回指定索引号(i)的结果  
  127.                                       Product product = (Product)hits.data(i);    
  128.  if(hits.highlighter(i).fragment("content ")!=null)  
  129.                 product.setName(hits.highlighter(i).fragment("content")); // 如果没有高亮内容时返回null     
  130.                                    
  131.                                       products.add(product);    
  132.                              }    
  133.                              qr.setResultlist(products);    
  134.                              qr.setTotalrecord(hits.length());    
  135.                              hits.close();    
  136.                    } catch (CompassException e) {    
  137.                             e.printStackTrace();    
  138.                             tx.rollback();    
  139.                    }finally{    
  140.                             if(session!=null && !session.isClosed()) session.close();    
  141.                    }    
  142.                    return qr;    
  143.          }    
  144. }    

 

补充说明:

一、 这两段代码具有一样的功能,下面的代码另外还多了个很重要的功能,自动选择正文中最匹配关键字的内容中的一部分输出。因为很多时候一篇文章几千字,我们只想显示有关键字的那部分的摘要,这时候这个功能就很方便。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Stringcontent = hits.highlighter(i) .fragment("content");   
  2.   
  3. String content =hits.highlighter(i).setTextTokenizer(CompassHighlighter.TextTokenizer.AUTO).fragment("content");   

 

二、另外在getContent()方法上的@SearchableProperty中还可以加入例如converter ="htmlPropertyConverter",主要是用来将文章中的HTML标签进行过滤获取纯文本,在建立到索引中。在配置文件中添加

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <bean id="compass" class="org.compass.spring.LocalCompassBean">    
  2. <property name="convertersByName">    
  3.             <map>    
  4.                 <entry key="htmlPropertyConverter">    
  5.                     <bean class="com.compass.converter.HtmlPropertyConverter"/>    
  6.                 </entry>    
  7.             </map>    
  8. </property>    
  9. </bean>   

然后就可以自己写实现类了,我也是网上看到的,给个链接http://blog.csdn.net/u010469430/article/details/12384347

 

三、多种查询方式

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. // 查询方式一:使用查询字符串(可以有查询语法)  
  2.  // CompassHits hits = session.find(queryString);  
  3.  // -----------------------------------------------------------------  
  4.  // 查询方式二:构建CompassQuery对象  
  5.  // 1,查询所有  
  6.  CompassQuery query1 = session.queryBuilder().matchAll();  
  7.    
  8.  // 2,关键词查询  
  9.  CompassQuery query2 = session.queryBuilder().term("title""lucene");  
  10.    
  11.  // 3,范围查询  
  12.  CompassQuery query3 = session.queryBuilder().between("id"515true);  
  13.    
  14.  // 4,通配符查询  
  15.  CompassQuery query4 = session.queryBuilder().wildcard("title""lu*n?");  
  16.    
  17.  // 5,短语查询  
  18.  // 设定精确间隔的匹配方式,写法1  
  19.  CompassMultiPhraseQueryBuilder qb = session.queryBuilder().multiPhrase("title");  
  20.  qb.add("lucene"0); // 第一个词位置从0开始  
  21.  qb.add("工作"2); // 第二个词位置从2开始  
  22.  CompassQuery query5 = qb.toQuery();  
  23.  // 设定精确间隔的匹配方式,写法2  
  24.  CompassQuery query6 = session.queryBuilder().multiPhrase("title")//  
  25.  .add("lucene"0// 第一个词位置从0开始  
  26.  .add("工作"2// 第二个词位置从2开始  
  27.  .toQuery();  
  28.  // 设定最多间隔的匹配方式  
  29.  CompassQuery query7 = session.queryBuilder().multiPhrase("title")//  
  30.  .add("lucene"//  
  31.  .add("工作"//  
  32.  .setSlop(5// 指定的词之间的最长间隔不超过5个词  
  33.  .toQuery();  
  34.  // 6,布尔查询  
  35.  CompassQuery query = session.queryBuilder().bool()//  
  36.  // .addMust(query)  
  37.  // .addMustNot(query)  
  38.  // .addShould(query)  
  39.  .addMust(query1)//  
  40.  .addMustNot(query3)//  
  41.  .toQuery();  
  42.  CompassHits hits = query.hits();  


 

四、当然上面可以不用编程式配置,而通过Compass compass= new CompassConfiguration().configure().bulidCompass();使用类似如下的配置文件。

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <compass-core-config xmlns="http://www.compass-project.org/schema/core-config"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.compass-project.org/schema/core-config  
  5.     http://www.compass-project.org/schema/compass-core-config-2.2.xsd">  
  6.   
  7.     <compass name="default">  
  8.   
  9.         <!-- 配置索引库的存储目录 -->  
  10.         <connection>  
  11.             <file path="e:/liuyan_index" />  
  12.         </connection>  
  13.           
  14.         <cache>  
  15.             <firstLevel type="org.compass.core.cache.first.NullFirstLevelCache" />  
  16.         </cache>  
  17.           
  18.         <mappings>  
  19.             <class name="com.sharp.liuyan.so.ArticleSo" />  
  20.         </mappings>  
  21.           
  22.         <settings>  
  23.             <!-- setting元素就像于property元素 -->  
  24.             <setting name="compass.engine.analyzer.default.type"   
  25.                 value="net.paoding.analysis.analyzer.PaodingAnalyzer"/>    
  26.             <!-- 配置高亮 -->  
  27.             <setting name="compass.engine.highlighter.default.formatter.simple.pre"   
  28.                 value="<font color='red'><b>"/>  
  29.             <setting name="compass.engine.highlighter.default.formatter.simple.post"  
  30.                 value="</b></font>"/>  
  31.                                      
  32.         </settings>  
  33.           
  34.     </compass>  
  35.   
  36. </compass-core-config>  


 

Compass Spring的集成

 

先思考一下compass不与spring集成时的情况。

我们将一个entity保存到数据库的同时,也要将该实体相关的数据信息保存到索引库中。所以代码常为一下情况:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Public  void saveStudent(Student stu){  
  2.   
  3.         hibernateTeplate.save(stu);//保存到数据库中  
  4.   
  5.       compassSession.save(stu);//保存到索引库中  
  6.   
  7. }  

我们有一点需要保证的是,必须在数据库保存成功后才能将实体对象保存到索引库中,然而在没有任何外界条件限制的情况先,数据库的事务和compass的事务是两个不同体系的事务,他们不可能自动的将事务并为一起。这样就无法保证整个操作的流程控制在同一个事务中,所以我们就要想办法来解决这个问题。

使用compassspring集成,能很好的解决这个问题,spring会为hibernatecompass提供同一个事务管理,将整个操作流程(如上的saveStudent()方法)纳入同一个事务支持当中。

下面看一下配置中JPA(hibernate)compassspring的集成:

其中JPA(hibernate)spring集成与前面完全一致,就是在后面加了一个compass的配置:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <aop:aspectj-autoproxy/>  
  2. <!-- 配置哪些包下的类需要自动扫描 -->  
  3. <context:component-scan base-package="cn.itcast"/>      
  4. <!-- 这里的itcast要与persistence.xml中的 <persistence-unit name="itcast " transaction-type="RESOURCE_LOCAL">中的name值要一致,这样才能找到相关的数据库连接 
  5. -->  
  6. <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">  
  7.         <property name="persistenceUnitName" value="itcast"/>  
  8. </bean>    
  9. <!-- 配置事物管理器 -->   
  10. <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">  
  11.         <property name="entityManagerFactory" ref="entityManagerFactory"/>  
  12. </bean>  
  13.   <!-- 配置使用注解来管理事物 -->   
  14. <tx:annotation-driven transaction-manager="transactionManager"/>  
  15. <!—compass对象相当于 hibernate中的sessionFactory,在整个应用中时单例,这里使用org.compass.spring.LocalCompassBean,表示由spring来生成并管理compass对象,生成该对象需要一些属性设置。  
  16.  -->  
  17. <bean id="compass" class="org.compass.spring.LocalCompassBean">  
  18. <!--  如果compass有单独的配置文件,可以从这里引入    
  19.         <property name="configLocation" value="classpath:compass.cfg.xml"/>    
  20.          -->    
  21.         <!-- 数据索引存储位置 -->    
  22.         <property name="connection" value="/lucene/indexes"/>       
  23. <!—配置compass的实体类映射-->  
  24.     <property name="classMappings">  
  25.         <list>  
  26.             <value>cn.itcast.bean.product.ProductInfo</value>  
  27.             <value>cn.itcast.bean.product.Brand</value>  
  28.             <value>cn.itcast.bean.product.ProductStyle</value>  
  29.             <value>cn.itcast.bean.product.ProductType</value>  
  30.         </list>  
  31.     </property>  
  32.     <!---compass相关的一些属性设置      
  33. <property name="compassSettings"><props>  
  34. -->  
  35.   
  36. <!—- 指定compass的默认分词器,为:paoding分词,paoding分词器是基于字典的分词器,所以最好字典,使用paoding分词器时,将paoding分词器压缩目录下的字典目录(dic)放到项目的src目录下,并将paoding分词的paoding-dic-home.properties文件拷贝到src下,并在该配置文件中指定字典dic的路径为:classpath:dic。如果需要自定义一些字词,只需在dic目录下的字典文件中加上该词即可。-->  
  37. <prop key="compass.engine.analyzer.default.type">  
  38.                 net.paoding.analysis.analyzer.PaodingAnalyzer  
  39. </prop>  
  40. <!—- compass索引库的位置 -->  
  41. <!-- file://e:/index 中以file://开头表示在硬盘上指定位置创建索引库-->  
  42. <!—  ram:// index 中以ram://开头表示在内存中创建索引库-->  
  43.             <prop key="compass.engine.connection">  
  44. file://e:/index  
  45. </prop>  
  46. <!-- 指定摘要文本的长度 -->    
  47. <prop key="compass.engine.highlighter.default.fragmenter.simple.size"> 200    
  48. </prop>    
  49. <!—- 对关键字进行高亮(highlighter)设置 -->  
  50.             <prop key="compass.engine.highlighter.default.formatter.simple.pre"><![CDATA[<font color='red'>]]>  
  51. </prop>  
  52.             <prop key="compass.engine.highlighter.default.formatter.simple.post"><![CDATA[</font>]]>  
  53. </prop>  
  54. <!-- transaction.factory用于指定compass的事务工厂,这里指定为spring提供的事务工厂类,该工厂类会从spring中获得当前的事务,compass就可以使用当前事务了 -->  
  55.             <prop key="compass.transaction.factory">  
  56. org.compass.spring.transaction.SpringSyncTransactionFactory  
  57. </prop>  
  58.         </props>  
  59.     </property>  
  60. <!—- spring中的事务是由事务管理器来管理的,上面的指定的compass的transaction.factory要从spring获得当前事务,就必须去访问spring的事务管理器,这里就指定了compass的事务工厂要访问的spring的事务管理器,该事务管理器在前面已经配置好了,和hibernate那个一致,这里只需要引用就可以了-->  
  61.     <property name="transactionManager" ref="transactionManager" />  
  62. </bean>  

 

按照上面的配置你仍然需要在代码中写相应的创建、删除索引的语句,在配置文件中添加下面的代码就可以一切都自动化了。 

CompassGps - Gps的核心模块,管理GpsDevice,有两种实现:SingleCompassGpsDualCompassGps

CompassGpsDevice - 处理各种数据源到索引的操作:JDBC, Hibernate,iBatis等。不能独立使用而必须融合到CompassGps中。

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <!-- SingleCompassGps 类是compass的GPS机制的实现类,spring在实例化该类的对象后,会立即执行init-method属性指定的SingleCompassGps中的start()方法,start方法用于启动 对 hibernate或JPA等持久化工具对实体类的增删改查的操作 的监听捕获,因为hibernate或JPA等的持久化操作都会触发一些生命周期事件,而GPS可以对这些生命周期事件进行监听捕获,从而可以使用compass同步的将实体类信息更新到索引库中去-->  
  2. <bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps" init-method="start" destroy-method="stop">  
  3. <!—GPS在监听到hibernate、JPA等对实体类的操作时,要使用compass对象将实体信息更新到索引库中,这里就是指出GPS要使用的compass对象,该compass对象在前面已经配置,这里只需要引用即可 -->  
  4.     <property name="compass" ref="compass" />  
  5.     <property name="gpsDevices">  
  6.         <list>  
  7. <bean class="org.compass.spring.device.SpringSyncTransactionGpsDeviceWrapper">  
  8.                 <property name="gpsDevice" >  
  9. <!—GPS要监听与实体类对象相关的操作的生命周期,就必须知道是什么产品的工具在对实体类进行操作,这些工具可能是hibernate,JPA等,本项目使用的是JPA,所以要配置JPA相关的驱动,用来监听JPA操作实体时生命周期所发生的变化-->  
  10.                 <bean class="org.compass.gps.device.jpa.JpaGpsDevice">  
  11.                     <!—- 这是设置的名字,随便取 -->  
  12.                     <property name="name" value="jpaDevice" />  
  13. <!—GPS要监听实体被操作的生命周期的变化,就需要去访问管理实体的工厂对象,这里指定entityManagerFactory 为前面配置的JPA提供的实体管理工厂-->  
  14.             <property name="entityManagerFactory" ref="entityManagerFactory" />  
  15. <!—        指定是否监听与实体相关的声明周期事件     -->  
  16.                 <property name="injectEntityLifecycleListener" value="true"/>  
  17.                 </bean>  
  18.                 </property>  
  19.             </bean>  
  20.         </list>  
  21. </property>  
  22. </bean>  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值