- 浏览: 850171 次
文章分类
- 全部博客 (365)
- java (124)
- spring mvc (21)
- spring (22)
- struts2 (6)
- jquery (27)
- javascript (24)
- mybatis/ibatis (8)
- hibernate (7)
- compass (11)
- lucene (26)
- flex (0)
- actionscript (0)
- webservice (8)
- rabbitMQ/Socket (15)
- jsp/freemaker (5)
- 数据库 (27)
- 应用服务器 (21)
- Hadoop (1)
- PowerDesigner (3)
- EJB (0)
- JPA (0)
- PHP (2)
- C# (0)
- .NET (0)
- html (2)
- xml (5)
- android (7)
- flume (1)
- zookeeper (0)
- 证书加密 (2)
- maven (1)
- redis (2)
- cas (11)
最新评论
-
zuxianghuang:
通过pom上传报错 Artifact upload faile ...
nexus上传了jar包.通过maven引用当前jar,不能取得jar的依赖 -
流年末年:
百度网盘的挂了吧???
SSO单点登录系列3:cas-server端配置认证方式实践(数据源+自定义java类认证) -
953434367:
UfgovDBUtil 是什么类
Java发HTTP POST请求(内容为xml格式) -
smilease:
帮大忙了,非常感谢
freemaker自动生成源代码 -
syd505:
十分感谢作者无私的分享,仔细阅读后很多地方得以解惑。
Nginx 反向代理、负载均衡、页面缓存、URL重写及读写分离详解
学习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总结起来就两句话:
Compass2.2的版本所用的Lucene2.4.1,Lucene2.4与目前的Lucene3.0相比:
但是Compass用起来舒服,学习成本不高,所以这里用Compass2.2对索引库进行操作.
所需jar包
Compass配置文件
先从Compass的文档中复制配置模板:
再对其进行详细配置:
<compass name="default">
<!-- 1,连接信息 -->
<connection>
<file path="./indexDir/" />
</connection>
<!-- 2,声明映射信息 -->
<mappings>
<class name="cn.domain.Article" />
</mappings>
</compass>
在Lucene里面,如果将对象的数据存储在索引库里面,需要先把对象转换为Document,这个工作在Compass里面会自动将其转为Document,在Lucene里面还需要指定哪些Field是可以搜索的,并且是否存储在缓存数据里面,那么Compass也要提供相应的配置才行,Compass如何做到呢?它会在主配置文件(compass.cfg.xml)中通过反射得到Class,得到该类上所有的注解信息,这就是映射信息的作用.用Article作为测试类,属性如下:
public class Article {
private Integer id;
private String title;
private String content;
再生成对应的getter、setter方法,我们要指明这个类的数据是可以被搜索到的,需要在类上添加注解:
@Searchable
public class Article {
这就表明这是一个可搜索对象,Compass会通过反射创造出该类的实例,所以一定要有无参的构造函数,并且有删除索引的需求,还有Field的配置等,对可搜索对象的所有要求为:
要有默认的构造方法
第二个条件主要是针对删除和更新的,因为之前对Compass的核心方法和Hibernate的核心方法进行了对比,删除索引是用delete()方法,delete()方法不是接收一个对象,因为你把对象给它,它也不知道对象与与对象之间是以什么为区别的,所以给它一个Class,它通过在主配置文件中的映射信息,反射出该类, 再用你提供的第二个参数,也就是唯一标识符,来找到索引,从而进行删除和更新的操作,这就是@SearchableId的作用.
在Lucene里面将对象转为Document对象的时候,需要保存的数据用Field对象来封装,封装的时候,要提供是否存储数据以及是否为数据建立索引等配置,这就是@SearchableProperty的作用.完整的对类的配置为下,以id作为唯一标识符:
@Searchable
public class Article {
// 对于唯一标识符,默认不可以进行搜索,除非明确的指定name属性。
// Compass2.2对于数字是使用toString()策略,对于数字属性应指定format属性。
// 如format="00000",表示数字存为5个字符,如果不足5个,前面用若干个0补齐。
@SearchableId(name = "id", format = "00000000")
private Integer id;
// name属性可以不写,默认当前属性(成员变量)的名称。
@SearchableProperty(name = "title", store = Store.YES, index = Index.ANALYZED)
private String title;
@SearchableProperty(name = "content", store = Store.YES, index = Index.ANALYZED)
private String content;
注意导包不要导错了,全是org.compass.annotations包中的.属性配置基本和Lucene里面一样.唯一需要注意的就是对数字的处理.如果在Compass的使用过程中出来问题,或者找不到索引之类的,一定要记得看你的数据类型.
创建索引的方式基本与Lucene相同,毕竟Compass是对Lucene的封装,思想是属于Lucene的.就像Hibernate使用Session需要先得到SessionFactory一样,Compass也需要获得SessionFactory,并且也是由Configuration对象来取得的:
public class ArticleDao {
private Compass compassSessionFactory;
public ArticleDao() {
CompassConfiguration cfg = new CompassConfiguration().configure();
compassSessionFactory = cfg.configure().buildCompass();
}
在Hibernate中,对于Session,SessionFactory只需要一个就够了,对于一个索引库,全局只有一个Compass对象就可以了:
@Test
public void createIndex(){
//准备好测试数据
Article article = new Article();
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
public void searchIndex() {
//获得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);
int count = hits.length();
for (int i = 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
public void deleteIndex(){
CompassSession session = CompassUtils.getSession();
CompassTransaction tx = session.beginTransaction();
session.delete(Article.class,1);
tx.commit();
session.close();
}
@Test
public void updateIndex(){
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>
<!-- 配置分词器类型 -->
<setting name="compass.engine.analyzer.default.type" value="jeasy.analysis.MMAnalyzer"></setting>
</settings>
这个分词器对中文支持比较好,采用的是词库分词,准确度较高.
接下来还要配置高亮器,配置高亮器主要有三点:前缀、后缀、高亮显示的摘要.同样是在主配置文件里面进行配置:
<!-- 3,其他配置 -->
<settings>
<!-- 高亮配置:摘要的长度(字符数量,默认为100) -->
<setting name="compass.engine.highlighter.default.fragmenter.simple.size" value="20" />
<!-- 高亮配置:显示效果的前缀 -->
<setting name="compass.engine.highlighter.default.formatter.simple.pre" value="<span class='keyword'>" />
<!-- 高亮配置:显示效果的后缀 -->
<setting name="compass.engine.highlighter.default.formatter.simple.post" value="</span>" />
<!-- 配置分词器类型 -->
<setting name="compass.engine.analyzer.default.type" value="jeasy.analysis.MMAnalyzer"></setting>
</settings>
注意,前缀和后缀中的标签,要转义,不然会和配置文件中的符号产生冲突!
@Test
public void highlighterIndex() {
CompassSession session = CompassUtils.getSession();
CompassTransaction tx = session.beginTransaction();
// 查询条件
String queryString = "love";
CompassHits hits = session.find(queryString);
int count = hits.length();
for (int i = 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
private float boostValue = 1F;
在实体里面增加这个属性,属性名无所谓,类型是float,最重要的是要有getter、setter方法和@SearchableBoostProperty,必须要有这处注解,Lucene才能在你调用相关方法的时候,通过反射获得有这个注解的属性名,在调用它的getter方法,得到值,那么在程序中就要增加一句代码:
//准备好测试数据
Article article = new Article();
article.setId(3);
article.setTitle("baby");
article.setContent("love you");
//设定比重,默认为1L
article.setBoostValue(2L);
其他地方都是一样的.除了对相关度得分的排序以外,还可能在搜索时使用某个属性的值进行排序.这也是可以的:
@Test
public void sortIndex() {
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();
int count = hits.length();
for (int i = 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
public void filterIndex() {
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();
int count = hits.length();
for (int i = 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
public void search() throws Exception {
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 = new ArrayList<Article>();
int count = hits.length(); // 总结果数
for (int i = 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的那一套,只是简单的封装一下而已.
发表评论
-
solr第一弹 autocomplete(自动补全)
2012-09-22 16:38 1460百度和google中都有 ... -
Compass将lucene、Spring、Hibernate三者结合
2012-09-01 10:29 1784Java代码 1.概述 Compass将 ... -
lucene3.0学习笔记之异常集锦(1)
2012-08-28 11:08 1118luceneJavaApachethread ... -
lucene3.0学习笔记(三)与paoding整合
2012-08-28 11:07 1210luceneApache.net 试过lucen ... -
lucene3.0学习笔记(二)index
2012-08-28 11:07 1009luceneApacheF# 1。IndexWr ... -
lucene3.0学习笔记(一)
2012-08-28 11:06 795luceneApacheCGIBlog工作 首先 ... -
Compass技术文档
2012-06-24 15:15 4322目录 一、原理描述:... 二、术语解释:... 三 ... -
struts2+spring+hibernate+compass 实现全文检索
2012-06-24 10:22 1610Compass是一流的开放源码JAVA搜索引擎框架,对于你的应 ... -
给你的网站加上站内搜索---Compass入门教程
2012-06-15 08:32 7208给你的网站加上站内搜索---Compass入门教程 ... -
COMPASS+spring 构建自己的搜索引擎
2012-06-12 13:06 1396在新架构中打算选择Compass或Hibernate Sear ...
相关推荐
### 基于Compass2.2与Spring结合建立索引的实例 #### 一、Compass简介 Compass是一个开源的.NET和Java框架,它为应用程序提供了完整的文本搜索功能。该框架支持多种搜索引擎(如Elasticsearch, Solr等),使得开发...
通过研究这个SSH2+Compass2.2搜索实例,开发者可以学习到如何在J2EE应用中整合多个框架以实现复杂的功能,如搜索引擎集成。此外,还会了解如何使用MyEclipse这样的IDE进行开发,以及如何管理和部署SQL数据库。这是一...
【Compass原理深入学习笔记】 Compass是一款基于Apache Lucene的全文搜索引擎框架,它为开发者提供了更高级别的抽象层,简化了搜索引擎的集成工作。在理解Compass之前,我们需要先了解全文检索的基本概念和原理。 ...
根据HTML页面压缩的可查询的Compass最新API,是个人 压缩成Chm的,支持索引和搜索功能,3分应该不贵吧.
Compass概念: 1:Compass相当于hb的SessionFactory 2:CompassSession相当于hb的Session 3:CompassTransaction相当于hb的transaction。 <br>Compass也是采用CompassConfiguration(装载配置和映射文件...
`compass学习笔记.doc`是一份关于Compass的学习文档,可能包含了使用Compass的基本步骤,常见问题解答,以及一些最佳实践。这份文档对于理解Compass的工作原理和实际应用是非常有价值的。 `lucene总结.chm`和`...
【标题】"Compass简单学习"所涉及的知识点主要集中在两个方面:一是对Compass工具的理解,二是如何使用Compass进行源码分析和开发辅助。Compass是一个强大的样式表(CSS)编译器,它基于Sass语言,帮助开发者更高效...
《深入探索Lucene+Compass技术与Ajax应用》 在当今的互联网开发中,数据检索和实时交互性已经成为不可或缺的功能。Lucene作为一个强大的全文搜索引擎库,为开发者提供了高效的文本搜索能力;Compass作为Lucene的一...
### Extjs 5 学习笔记之 SenchaCmd 深入解析 #### 一、SenchaCmd 的简介 SenchaCmd 是一个跨平台的命令行工具,它为基于 ExtJS 和 Sencha Touch 应用程序的开发周期提供了全面的支持。从创建应用程序的基础结构到...
##### 2.2 Hibernate 简介 - **Hibernate** 是一个 ORM 框架,可以将 Java 应用程序中的对象与数据库中的表格自动对应起来。 - **优点**:简化了数据库操作,提高了开发效率。 - **缺点**:虽然适合处理关系型数据库...
此项目对于理解Compass和Lucene在实际应用中的使用,以及如何结合SSH框架开发Java Web应用具有很高的学习价值。通过分析和研究这个项目,开发者可以深入掌握Java全文搜索引擎的实现,以及如何在SSH框架下组织和管理...
本文档总结了Compass和WellPlan的学习笔记,涵盖了油气工业中常用的井trajectory设计和分析、Well Planning和设计等方面的知识点。 一、井trajectory设计和分析 井trajectory设计和分析是油气工业中非常重要的一环...
COMPASS 教程Pdf COMPASS 是一款专业的油气田设计和生产软件,主要用于油气田的规划、设计和生产过程。下面是 COMPASS 的一些重要知识点: 1. COMPASS WELLPLAN FOR WINDOWS 功能简介:COMPASS 的核心功能包括 ...
Compass搜索引擎技术是一种基于Lucene的全文检索框架,它提供了更高级别的API和集成机制,使得在Java应用程序中实现搜索引擎功能变得更加便捷。Compass的主要目标是将全文索引能力无缝地融入到现有的业务应用程序中...
MongoDB Compass是MongoDB官方提供的一款图形化管理工具,它为MongoDB数据库的使用者提供了直观的界面,方便进行数据浏览、查询、操作以及性能分析。MongoDB Compass 1.15.1是这个系列的一个版本,它无需安装,可以...
Compass 是一个强大的开源搜索引擎框架,它建立在 Lucene 的基础之上,为 Java 开发者提供了更为简洁的搜索引擎 API。Compass 的设计目标是简化搜索引擎的集成,使其能够无缝地与现有的应用程序,如 Hibernate 和 ...