学习Compass是个很快速的过程,它不像其他框架需要花很多时间学习它的API和了解它的工作流程.似乎Compass就是两个框架的组合版本.
为什么这样说呢?看下它的工作流程就知道了:
这个结构和Hibernate很相像,无非就是Hibernate把JDBC封装了一把.所以从结构上来说,只要我们了解了Hibernate,就已经对Compass有了了解.那么Hibernate需要提供API和配置文件来对JDBC进行操作,那么Compass呢?Compass不仅从结构上模仿了Hibernate,就连API风格也不尽相同.我们把它和Hibernate的API做个对比就知道了:
Hibernate API |
Compass API |
Configration cfg = new Configuration().configue(); |
CompassConfiguration cfg = new CompassConfiguration().configure(); |
SessionFactory sf = cfg.buildSessionFactory(); |
Compass compass = cfg.buildCompass(); |
Session session = sf.openSession(); |
CompassSession session = compass.openSession(); |
Transaction tx = session.beginTransaction(); |
CompassTransaction tx = session.beginTransaction(); |
session.xxx(); // do something |
session.xxx(); // do something |
tx.commit(); |
tx.commit(); |
session.close(); |
session.close(); |
再把两个session的核心方法比较一下:
Hibernate session API |
CompassSession API |
|
save(Object) |
create(Object) |
建立索引 |
saveOrUpdate(Object) |
save(Object) |
保存或更新 |
delete(Object) |
delete(Class, ids...) |
删除索引 |
get() |
get() |
获取 |
createQuery(hql).list() |
find(String) |
使用查询字符串查询 |
所以说,Compass与Hibernate极为相似,Compass总结起来就两句话:
Hibernate的风格
Lucene的思想
Compass2.2的版本所用的Lucene2.4.1,Lucene2.4与目前的Lucene3.0相比:
API的差别很大,代码不能通用
3.0效率更高
但是Compass用起来舒服,学习成本不高,所以这里用Compass2.2对索引库进行操作.
所需jar包
Compass配置文件
先从Compass的文档中复制配置模板:
再对其进行详细配置:
< compassname ="default" >
<!-- 1,连接信息 -->
< connection >
< filepath ="./indexDir/"/>
</ connection >
<!-- 2,声明映射信息 -->
< mappings >
< classname ="cn.domain.Article"/>
</ mappings >
</ compass >
在Lucene里面,如果将对象的数据存储在索引库里面,需要先把对象转换为Document,这个工作在Compass里面会自动将其转为Document,在Lucene里面还需要指定哪些Field是可以搜索的,并且是否存储在缓存数据里面,那么Compass也要提供相应的配置才行,Compass如何做到呢?它会在主配置文件(compass.cfg.xml)中通过反射得到Class,得到该类上所有的注解信息,这就是映射信息
的作用.用Article作为测试类,属性如下:
publicclassArticle {
privateInteger id;
privateString title;
privateString content;
再生成对应的getter、setter方法,我们要指明这个类的数据是可以被搜索到的,需要在类上添加注解:
@Searchable
publicclassArticle {
这就表明这是一个 可搜索对象,Compass会通过反射创造出该类的实例,所以一定要有
无参的构造函数,并且有删除索引的需求,还有Field的配置等,对可搜索对象的所有要求为:
要有默认的构造方法
在类上要有:@Searchable
要有一个唯一标识符的属性:@SearchableId
其他的属性用:@SearchableProperty
第二个条件主要是针对删除和更新的,因为之前对Compass的核心方法和Hibernate的核心方法进行了对比,删除索引是用delete()方法,delete()方法不是接收一个对象,因为你把对象给它,它也不知道对象与与对象之间是以什么为区别的,所以给它一个Class,它通过在主配置文件中的映射信息,反射出该类, 再用你提供的第二个参数,也就是唯一标识符,来找到索引,从而进行删除和更新的操作,这就是@SearchableId的作用
.
在Lucene里面将对象转为Document对象的时候,需要保存的数据用Field对象来封装,封装的时候,要提供是否存储数据以及是否为数据建立索引等配置,这就是@SearchableProperty的作用
.完整的对类的配置为下,以id作为唯一标识符:
@Searchable
publicclassArticle {
// 对于唯一标识符,默认不可以进行搜索,除非明确的指定name属性。
// Compass2.2对于数字是使用toString()策略,对于数字属性应指定format属性。
// 如format="00000",表示数字存为5个字符,如果不足5个,前面用若干个0补齐。
@SearchableId(name ="id", format ="00000000")
privateInteger id;
// name属性可以不写,默认当前属性(成员变量)的名称。
@SearchableProperty(name ="title", store = Store.YES, index = Index.ANALYZED)
privateString title;
@SearchableProperty(name ="content", store = Store.YES, index = Index.ANALYZED)
privateString content;
注意导包不要导错了,全是 org.compass.annotations包中的.属性配置基本和Lucene里面一样.唯一需要注意的就是对数字的处理.如果在Compass的使用过程中出来问题,或者找不到索引之类的,一定要记得看你的数据类型.
创建索引的方式基本与Lucene相同,毕竟Compass是对Lucene的封装,思想是属于Lucene的.就像Hibernate使用Session需要先得到SessionFactory一样,Compass也需要获得SessionFactory,并且也是由Configuration对象来取得的:
publicclassArticleDao {
privateCompass compassSessionFactory;
publicArticleDao() {
CompassConfiguration cfg =newCompassConfiguration().configure();
compassSessionFactory = cfg.configure().buildCompass();
}
在Hibernate中,对于Session,SessionFactory只需要一个就够了,对于一个索引库,全局只有一个Compass对象就可以了:
@Test
publicvoidcreateIndex(){
//准备好测试数据
Article article =newArticle();
article.setId(1);
article.setTitle("baby");
article.setContent("love you");
//获得Session
CompassSession session = compassSessionFactory.openSession();
//这个事务是针对索引库的事务
CompassTransaction tx = session.beginTransaction();
session.save(article);
tx.commit();
session.close();//一定要记得关闭
}
简单的查询,就像Lucene的查询字符串一样.
@Test
publicvoidsearchIndex() {
//获得Session
CompassSession session = compassSessionFactory.openSession();
//这个事务是针对索引库的事务
CompassTransaction tx = session.beginTransaction();
//找到一条结果数
// Article article = session.load(Article.class, 1);
// System.out.println(article.getId());
// System.out.println(article.getTitle());
// System.out.println(article.getContent());
String queryString ="love";
CompassHits hits = session.find(queryString);
intcount = hits.length();
for(inti = 0; i < count; i++) {
Article article = (Article) hits.data(i);
System.out.println(article.getId());
System.out.println(article.getTitle());
System.out.println(article.getContent());
}
tx.commit();
session.close();//一定要记得关闭
}
这只是一个简单增加索引和查询索引的例子,权当做
Hello World 吧.
每次使用Session都要从SessionFactory中获取,无疑是很麻烦的,不如把SessionFactory维护在工具类里面,全局只有一个,在用一个静态方法得到一个Session.
@Test
publicvoiddeleteIndex(){
CompassSession session = CompassUtils.getSession();
CompassTransaction tx = session.beginTransaction();
session.delete(Article.class,1);
tx.commit();
session.close();
}
@Test
publicvoidupdateIndex(){
CompassSession session = CompassUtils.getSession();
CompassTransaction tx = session.beginTransaction();
Article article = session.get(Article.class, 1);
article.setContent("love love");
session.save(article);
tx.commit();
session.close();
}
注意,如果唯一标识符是数字,并且没有在实体类里面对唯一标识符使用format属性,则以上代码获取不到!
默认的分词是 标准分词器
,这个分词器对中文采取的是 单字分词 ,根本没办法使用.一般做法是用第三方的分词器,常用的有极易分词、庖丁分词、IKAnalyzer等.要使用分词器,需要在Compass的主配置文件里面进行配置,这里采用极易分词:
<!-- 3,其他配置 -->
< settings >
<!-- 配置分词器类型 -->
< settingname ="compass.engine.analyzer.default.type" value ="jeasy.analysis.MMAnalyzer" ></ setting >
</ settings >
这个分词器对中文支持比较好,采用的是词库分词,准确度较高.
接下来还要配置 高亮器
,配置高亮器主要有三点:前缀、后缀、高亮显示的摘要.同样是在主配置文件里面进行配置:
<!-- 3,其他配置 -->
< settings >
<!-- 高亮配置:摘要的长度(字符数量,默认为100) -->
< settingname ="compass.engine.highlighter.default.fragmenter.simple.size"value ="20" />
<!-- 高亮配置:显示效果的前缀 -->
< settingname ="compass.engine.highlighter.default.formatter.simple.pre" value ="<span class='keyword'>"/>
<!-- 高亮配置:显示效果的后缀 -->
< settingname ="compass.engine.highlighter.default.formatter.simple.post" value ="</span>"/>
<!-- 配置分词器类型 -->
< settingname ="compass.engine.analyzer.default.type" value ="jeasy.analysis.MMAnalyzer" ></ setting >
</ settings >
注意,前缀和后缀中的标签,要转义,不然会和配置文件中的符号产生冲突!
@Test
publicvoidhighlighterIndex() {
CompassSession session = CompassUtils.getSession();
CompassTransaction tx = session.beginTransaction();
// 查询条件
String queryString ="love";
CompassHits hits = session.find(queryString);
intcount = hits.length();
for(inti = 0; i < count; i++) {
Article article = (Article) hits.data(i);
// -------------------------
// 进行高亮操作,一次高亮一个属性值
// 返回高亮后的一段文本摘要,原属性值不会改变
// 如果当前高亮的属性值中没有出现关键字,则返回null.
String text = hits.highlighter(i).fragment("content");
if(text != null){
// 使用的高亮后的文本替原文本
article.setContent(text);
}
System.out.println(article.getId());
System.out.println(article.getTitle());
System.out.println(article.getContent());
}
tx.commit();
session.close();
}
一般来说搜索结果的排序和Lucene里面是一样的,按照
相关度得分 进行排序,在实际应用中,往往需要人工操纵得分,比如给了推广费之类的,既然有这种需求,自然就有这种做法,和Lucene的不同之处在于,Lucene在添加索引时
控制相关度得分的比重,Compass也是在添加索引时控制,不过需要在实体类里面增加一个属性和它的getter、setter方法,这个属性决定了所有这个类的数据的相关度得分的比重,也就是说可以让只要是这个实体类的数据,就能比别的类的数据得分要高,并且只要是设置了这个属性,就能在添加索引时控制相关度得分的比重:
@SearchableBoostProperty
privatefloatboostValue = 1F;
在实体里面增加这个属性,属性名无所谓,类型是
float ,最重要的是要有 getter、setter方法和@SearchableBoostProperty,必须要有这处注解,Lucene才能在你调用相关方法的时候,通过反射获得有这个注解的属性名,在调用它的getter方法,得到值,那么在程序中就要增加一句代码:
//准备好测试数据
Article article =newArticle();
article.setId(3);
article.setTitle("baby");
article.setContent("love you");
//设定比重,默认为1L
article.setBoostValue(2L);
其他地方都是一样的.除了对相关度得分的排序以外,还可能在搜索时使用某个属性的值进行排序.这也是可以的:
@Test
publicvoidsortIndex() {
CompassSession session = CompassUtils.getSession();
CompassTransaction tx = session.beginTransaction();
// 查询条件
String queryString ="love";
//CompassHits hits = session.find(queryString);
CompassQuery query = session.queryBuilder().queryString(queryString).toQuery();
query.addSort("id");
CompassHits hits = query.hits();
intcount = hits.length();
for(inti = 0; i < count; i++) {
Article article = (Article) hits.data(i);
System.out.println(article.getId());
System.out.println(article.getTitle());
System.out.println(article.getContent());
}
tx.commit();
session.close();
}
只需要在得到搜索结果之前做一点改动.先得到CompassQuery对象,调用这个对象的addSort()方法增加排序规则.像上述一样,则是按升序进行排序,也可以替换成下面这句使用降序排列:
query.addSort("id",SortDirection.REVERSE);
注意,指定参与排序的字段时,参与排序的字段必须要是Index.NOT_ANALYZED,否则分词后无法找到!
有时候也会使用到 过滤器
对搜索结果进行过滤.
@Test
publicvoidfilterIndex() {
CompassSession session = CompassUtils.getSession();
CompassTransaction tx = session.beginTransaction();
//查询条件
String queryString ="love";
//得到CompassQuery对象,准备查询
CompassQuery query = session.queryBuilder().queryString(queryString).toQuery();
/**
* 增加过滤条件,between第三、四个参数分别代表是否包含下边界和上边界
*/
CompassQueryFilter filter = session.queryFilterBuilder().between("id", 2, 3, true, true);
//添加过滤器
query.setFilter(filter);
CompassHits hits = query.hits();
intcount = hits.length();
for(inti = 0; i < count; i++) {
Article article = (Article) hits.data(i);
System.out.println(article.getId());
System.out.println(article.getTitle());
System.out.println(article.getContent());
}
tx.commit();
session.close();
}
但是使用过滤器是 效率很低
的做法,使用查询字符串可以获得更高的效率,而且可以达到同样的效果.下面就对 各种查询进行简要说明:
@Test
publicvoidsearch()throwsException {
CompassSession session = CompassUtils.openSession();
CompassTransaction tx = session.beginTransaction();
// 查询方式一:使用查询字符串(可以有查询语法)
// CompassHits hits = session.find(queryString);
// -----------------------------------------------------------------
// 查询方式二:构建CompassQuery对象
// 1,查询所有
CompassQuery query1 = session.queryBuilder().matchAll();
// 2,关键词查询
CompassQuery query2 = session.queryBuilder().term("title","lucene");
// 3,范围查询
CompassQuery query3 = session.queryBuilder().between("id", 5, 15, true);
// 4,通配符查询
CompassQuery query4 = session.queryBuilder().wildcard("title","lu*n?");
// 5,短语查询
// 设定精确间隔的匹配方式,写法1
CompassMultiPhraseQueryBuilder qb = session.queryBuilder().multiPhrase("title");
qb.add("lucene", 0);// 第一个词位置从0开始
qb.add("工作", 2);// 第二个词位置从2开始
CompassQuery query5 = qb.toQuery();
// 设定精确间隔的匹配方式,写法2
CompassQuery query6 = session.queryBuilder().multiPhrase("title")//
.add("lucene", 0)// 第一个词位置从0开始
.add("工作", 2)// 第二个词位置从2开始
.toQuery();
// 设定最多间隔的匹配方式
CompassQuery query7 = session.queryBuilder().multiPhrase("title")//
.add("lucene")//
.add("工作")//
.setSlop(5)// 指定的词之间的最长间隔不超过5个词
.toQuery();
// 6,布尔查询
CompassQuery query = session.queryBuilder().bool()//
// .addMust(query)
// .addMustNot(query)
// .addShould(query)
.addMust(query1)//
.addMustNot(query3)//
.toQuery();
// -------------------------------
CompassHits hits = query.hits();
// 处理结果
List<Article> list =newArrayList<Article>();
intcount = hits.length();// 总结果数
for(inti = 0; i < hits.length(); i++) {
Article article = (Article) hits.data(i);
list.add(article);
}
tx.commit();
session.close();
// -----------------------------------------------------------------
// 显示结果
System.out.println("====== 符合条件的总记录数为:"+ count +" ======");
for(Article a : list) {
System.out.println("--------------> id = "+ a.getId());
System.out.println("title = "+ a.getTitle());
System.out.println("content= "+ a.getContent());
}
}
基本上还是Lucene的那一套,只是简单的封装一下而已.
|
相关推荐
Chapter 1, Getting Started with Sass and Compass, explains, in layman's terms, what Sass and Compass are, how they relate, and how to get them installed and ready to use. Chapter 2, Setting Up a Sass ...
compass教程.pdf
compass_使用详解.pdf compass_教程 compass_试用案例。
Compass是第一个实现java搜索引擎的开源框架,它是基于Lucene之上的,提供更简单的搜索引擎API,事务支持,对象到搜索引擎映射(Annotations
Compass Bar Pro是一个功能强大的UI组件,可让您通过所有有用的功能(例如标记(兴趣点)或可自定义的north)在游戏中显示精美的Compass。它完全适合您的冒险,RPG,FPS或生存/探索游戏。 它提供了两种类型的指南针...
罗氏血糖管理软件Accu-Chek Compass V1.3.0.8 软件简体中文完全汉化补丁,本人原创汉化,友情分享!(本软件适用于使用罗氏诊断公司出品的血糖测量仪表的糖尿病患者)。
Compass_入门指南 Compass_入门文档
Compass是一个强大的,事务的,高性能的对象/搜索引擎映射(OSEM:object/search engine mapping)与一个Java持久层框架.内容包括compass的jar包及从网上搜集的相关学习资料. 附两个不错的资料地址: ...
MongoDB图形化管理工具 MongoDB Compass
compass文档资料
Sass和Compass 实战
Compass原理深入学习笔记,对于compass知识的一个梳理,希望对大家有用
compass annotation关联关系
这个是mongodb-compass的1.23最新版本。花了我好长时间才下载完。各位请给我个赞 这个是mongodb-compass的1.23最新版本。花了我好长时间才下载完。各位请给我个赞 这个是mongodb-compass的1.23最新版本。花了我好长...
compass搜索引擎技术 eclipse mysql 实现像google的搜索功能
mongodb安装包和compass mongodb安装包和compass mongodb安装包和compass 可在node学习过程中使用
Think of Sass and Compass as power tools that allow you to paint with remarkable speed and precision.Sass and Compass in Action is a hands-on guide to stylesheet authoring using these two ...
mongodb官方客户端可视化工具compass-1.26.1-win32-x64
Compass需要的包3:compass-core.jar
这个是compass整合ssh的例子,最重要的一点是一对多的关联这方面,寡人整了一天才把compass关联搞定,网上有关compass的资源太少了,不想让以后的人这么为难,咱就上传个我自己的练习吧,有较为详细的注释,希望能对...