- 浏览: 520222 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (422)
- 重要 (12)
- BUG解决备忘录 (32)
- 环境搭建 (17)
- 开源组件 (4)
- 数据库 (16)
- 设计模式 (4)
- 测试 (3)
- javascript (5)
- Android (14)
- jdk相关 (9)
- struts2 (10)
- freemark (3)
- 自定义扩展及工具类 (5)
- jdk5新特性及java基础 (13)
- ssh及其他框架 (15)
- linux (32)
- tcp-ip http协议 (8)
- 服务器集群与负载均衡 (34)
- 项目管理相关 (11)
- 实用小技术 (10)
- 架构相关 (14)
- firefox组件 (11)
- spider (6)
- 产品设计 (11)
- PHP (1)
- ws (4)
- lucene (10)
- 其他 (2)
- BI (1)
- NoSQL (3)
- gzip (1)
- ext (4)
- db (6)
- socket (1)
- 源码阅读 (2)
- NIO (2)
- 图片处理 (1)
- java 环境 (2)
- 项目管理 (4)
- 从程序员到项目经理(一):没有捷径 (1)
- bug (1)
- JAVA BASE (8)
- 技术原理 (0)
- 新框架新技术 (1)
- 量化与python (1)
- 系统编程 (0)
- C语言 (0)
- 汇编 (0)
- 算法 (0)
最新评论
-
hyspace:
别逗了,最后一个算法根本不是最优的,sort(function ...
数组去重——一道前端校招试题 -
washingtin:
楼主能把策略和路由的类代码贴出来吗
Spring + iBatis 的多库横向切分简易解决思路 -
sdyjmc:
初略看了一下,没有闹明白啊,均衡负载使用Nginx,sessi ...
J2EE集群原理 I -
shandeai520:
谢谢大神!请教大神一个问题:假如我有三台服务器,连接池的上限是 ...
集群和数据库负载均衡的研究 -
hekuilove:
给lz推荐一下apache commonsStringUtil ...
request 获取 ip
- 开始之前
- 什么是Compass
- 与Spring、iBatis的整合
- 与Lucene的比较
- 经验总结
- 相关资源
开始之前
本文是Compass的入门指引,通过实例介绍了Compass与iBatis、Spring的整合,适合不了解Compass的读者,但要求读者了解Lucene、Spring和iBatis,写过一些简单的应用。
文中使用的软件包:
什么是Compass
Compass是一个Java搜索框架。它封装了Lucene,增加了一些Lucene不支持的特性(例如实时更新索引),支持各种数据(Java对象、xml、json)到索引的映射,支持各种数据源(JDBC, Hibernate, iBatis)。
图解(看得烦的直接跳过看下面的例子吧):
- Compass - 一般在程序启动时建立并被整个程序共享,主要用于建立CompassSession并通过其管理索引数据。
- CompassSession - 用于处理数据的session。
- CompassTransaction - 手动进行事务管理,如果不使用,Compass会自动管理事务。
- CompassTemplate - 将session和transaction透明化。
- 数据到索引的各种映射 - OSEM, XSEM, JSEM, RSEM。支持通过程序、XML、JSON进行配置。
- CompassGps - Gps的核心模块,管理GpsDevice,有两种实现:SingleCompassGps和DualCompassGps。
- CompassGpsDevice - 处理各种数据源到索引的操作:JDBC, Hibernate, iBatis等。不能独立使用而必须融合到CompassGps中。
与Spring、iBatis的整合
建索引
1、假设Spring + iBatis的框架已经搭建好。
2、配置Domain的OSEM
- @Searchable (alias= "user" )
- public class User {
- @SearchableId
- private int id;
- @SearchableProperty (index=Index.ANALYZED, store=Store.YES)
- private String name; // 姓名
- @SearchableProperty (index=Index.NOT_ANALYZED, store=Store.YES)
- private String gender; // 性别
- @SearchableProperty (index=Index.NOT_ANALYZED, store=Store.YES)
- private int age; // 年龄
- public User() {
- }
- public User(String name, String gender, int age) {
- setName(name);
- setGender(gender);
- setAge(age);
- }
- public int getId() {
- return id;
- }
- public void setId( int id) {
- this .id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this .name = name;
- }
- public String getGender() {
- return gender;
- }
- public void setGender(String gender) {
- this .gender = gender;
- }
- public int getAge() {
- return age;
- }
- public void setAge( int age) {
- this .age = age;
- }
- }
@Searchable(alias="user") public class User { @SearchableId private int id; @SearchableProperty(index=Index.ANALYZED, store=Store.YES) private String name; // 姓名 @SearchableProperty(index=Index.NOT_ANALYZED, store=Store.YES) private String gender; // 性别 @SearchableProperty(index=Index.NOT_ANALYZED, store=Store.YES) private int age; // 年龄 public User() { } public User(String name, String gender, int age) { setName(name); setGender(gender); setAge(age); } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
其实就是加几个Annotation而已。看到Index.ANALYZED、Store.YES这些东西,用过Lucene的应该大概都明白了吧。
- @Searchable - 指明该类可被映射至索引,alias参数是这一类索引对象的别名。
- @SearchableId - 索引对象的id,在同一类索引对象(同一个alias)中唯一标识一个对象。
- @SearchableProperty - 指示一个类属性如何被索引,index和store参数类似Lucene。
3、建立LocalCompassBean,配置索引文件存放路径和进行映射的domain。
- < bean id = "compass" class = "org.compass.spring.LocalCompassBean" >
- < property name = "compassSettings" >
- < props >
- <!-- 索引文件保存路径 -->
- < prop key = "compass.engine.connection" > /home/index/compasstest </ prop >
- </ props >
- </ property >
- < property name = "classMappings" > <!-- 进行映射的domain -->
- < list >
- < value > ren.domain.User </ value >
- < value > ren.domain.Book </ value >
- </ list >
- </ property >
- </ bean >
<bean id="compass" class="org.compass.spring.LocalCompassBean"> <property name="compassSettings"> <props> <!-- 索引文件保存路径 --> <prop key="compass.engine.connection">/home/index/compasstest</prop> </props> </property> <property name="classMappings"> <!-- 进行映射的domain --> <list> <value>ren.domain.User</value> <value>ren.domain.Book</value> </list> </property> </bean>
4、建立SqlMapClientGpsDevice,配置iBatis的sqlMapClient和获取数据进行索引的SQL语句id。
- < bean id = "ibatisGpsDevice" class = "org.compass.gps.device.ibatis.SqlMapClientGpsDevice" >
- < property name = "name" value = "ibatis" />
- < property name = "sqlMapClient" >
- < ref bean = "sqlMapClient" /> <!-- 引用项目中已经定义的ibatis的sqlMapClient -->
- </ property >
- < property name = "selectStatementsIds" > <!-- 对这些SQL查询的结果进行索引 -->
- < list >
- < value > user.getAllUsers </ value >
- < value > book.getAllBooks </ value >
- </ list >
- </ property >
- </ bean >
<bean id="ibatisGpsDevice" class="org.compass.gps.device.ibatis.SqlMapClientGpsDevice"> <property name="name" value="ibatis" /> <property name="sqlMapClient"> <ref bean="sqlMapClient" /> <!-- 引用项目中已经定义的ibatis的sqlMapClient --> </property> <property name="selectStatementsIds"> <!-- 对这些SQL查询的结果进行索引 --> <list> <value>user.getAllUsers</value> <value>book.getAllBooks</value> </list> </property> </bean>
5、建立CompassGps(SingleCompassGps或DualCompassGps),引用前面的compass和device。
- < bean id = "compassGps" class = "org.compass.gps.impl.SingleCompassGps"
- init-method = "start" destroy-method = "stop" >
- < property name = "compass" ref = "compass" />
- < property name = "gpsDevices" >
- < list >
- < ref local = "ibatisGpsDevice" />
- </ list >
- </ property >
- </ bean >
<bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps" init-method="start" destroy-method="stop"> <property name="compass" ref="compass" /> <property name="gpsDevices"> <list> <ref local="ibatisGpsDevice"/> </list> </property> </bean>
6、最后,直接调用CompassGps.index()方法建立索引。
- @Component
- @Qualifier ( "indexBuilder" )
- public class IndexBuilder {
- @Autowired
- @Qualifier ( "compassGps" )
- private CompassGps compassGps;
- public void buildIndex() {
- compassGps.index(); // 一行代码搞定
- }
- }
@Component @Qualifier("indexBuilder") public class IndexBuilder { @Autowired @Qualifier("compassGps") private CompassGps compassGps; public void buildIndex() { compassGps.index(); // 一行代码搞定 } }
查索引
1、建立CompassTemplate,引用LocalCompassBean。
- < bean id = "compassTemplate" class = "org.compass.core.CompassTemplate" >
- < property name = "compass" >
- < ref bean = "compass" />
- </ property >
- </ bean >
<bean id="compassTemplate" class="org.compass.core.CompassTemplate"> <property name="compass"> <ref bean="compass" /> </property> </bean>
2、使用CompassTemplate.execute(CompassCallback<T>)进行查询。
- @Component
- @Qualifier ( "indexSearcher" )
- public class IndexSearcher {
- @Autowired
- @Qualifier ( "compassTemplate" )
- private CompassTemplate compassTemplate;
- /**
- * 搜索用户
- */
- public List<User> searchUser( final String name, final String gender, final int age) {
- return compassTemplate.execute( new CompassCallback<List<User>>() {
- public List<User> doInCompass(CompassSession session) throws CompassException {
- CompassQueryBuilder builder = session.queryBuilder();
- String queryString = "" ;
- if (!StringUtils.isBlank(name)) {
- queryString += "and user.name:" + name;
- }
- if (!StringUtils.isBlank(gender)) {
- queryString += "and user.gender:" + gender;
- }
- if (age > 0 ) {
- queryString += "and user.age:" + age;
- }
- CompassQuery query = builder.queryString(queryString).toQuery();
- query.addSort( "user.age" , SortPropertyType.INT, SortDirection.REVERSE);
- CompassHits hits = query.hits();
- List<User> list = new ArrayList<User>();
- for (CompassHit hit : hits) {
- list.add((User)hit.data());
- }
- return list;
- }
- });
- }
- }
@Component @Qualifier("indexSearcher") public class IndexSearcher { @Autowired @Qualifier("compassTemplate") private CompassTemplate compassTemplate; /** * 搜索用户 */ public List<User> searchUser(final String name, final String gender, final int age) { return compassTemplate.execute(new CompassCallback<List<User>>() { public List<User> doInCompass(CompassSession session) throws CompassException { CompassQueryBuilder builder = session.queryBuilder(); String queryString = ""; if (!StringUtils.isBlank(name)) { queryString += "and user.name:" + name; } if (!StringUtils.isBlank(gender)) { queryString += "and user.gender:" + gender; } if (age > 0) { queryString += "and user.age:" + age; } CompassQuery query = builder.queryString(queryString).toQuery(); query.addSort("user.age", SortPropertyType.INT, SortDirection.REVERSE); CompassHits hits = query.hits(); List<User> list = new ArrayList<User>(); for (CompassHit hit : hits) { list.add((User)hit.data()); } return list; } }); } }
拼查询字符串这里写得比较累赘,小朋友不要学~
与Lucene的比较
1、Compass有比Lucene更易用的API(废话,封装了Lucene嘛),例如支持直接更新记录(因为resource类似数据库记录,含有主键)。像上面的建索引过程,如果用Lucene,肯定得写很多Java代码。
2、支持整合各种ORM框架和Spring,减少了代码量。例如上面例子中整合iBatis,直接几行配置就搞定了。
3、效率问题?感觉Lucene的API用起来老是不顺手,Compass这样封装虽然方便了,但有些担心会不会降低了性能,于是做了个简单的测试,分别索引4万条记录,结果是
Compass: 12203 ms.
Lucene: 9797 ms.
Compass比Lucene慢了大约25%,当然这个测试十分粗略,结果仅供参考。
经验总结
1、对多个表建索引后进行搜索,在添加排序条件时,如果不指定SortPropertyType,那么在没有指定converter的字段上排序时会抛Exception:
java.lang.RuntimeException: field "gender" does not appear to be indexed
但如果只对单个表建索引,不会有这个问题。应该是Compass的一个bug,不知道新版本有没有解决。
2、最好自己封装排序字段和分页。
3、总结,Compass比较适用于逻辑不太复杂的应用,会比Lucene少写很多代码。但如果需要一些较为特殊的需求,或者对效率要求比较高,还是用Lucene吧。
相关资源
Compass入门指南:http://www.yeeach.com/2008/03/23/compass-%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97/
全文检索的基本原理:http://blog.csdn.net/forfuture1978/archive/2009/10/22/4711308.aspx
大型网站的Lucene应用:http://www.luanxiang.org/blog/archives/605.html
写在后面
这篇文章是根据自己的一次演讲整理出来的,主要就是PPT内容 + 代码。演讲和写文章确实很不同,感觉很多地方还说不清楚,因为内容太多了吧,看来自己的书面组织能力还有待提高啊~
发表评论
-
SolrJ
2012-07-31 20:42 0http://www.ibm.com/developerwor ... -
lucene FilteredQuery
2010-12-28 20:49 1621FilteredQuery包含两个成员变量: Query ... -
ibatis insert 返回对象
2010-12-27 23:09 1398<!-- Insert example, using t ... -
Compass 入门指南
2010-12-23 22:28 948在新架构中打算选 ... -
使用 Compass 第三方框架维护索引库数据
2010-12-22 16:59 1300使用 Compass 第三方框架维护索引库数据 ... -
Lucene搜索方法总结
2010-12-22 16:28 898更多lucene信息欢迎查看http://summerbell ... -
lucene的分组查询(类似sql的group by)的解决方法
2010-12-22 15:42 1458通过lucene搜索去除相同结果。 在网上找了很久到没有答案 ... -
MyEclipse手动修改WebRoot目录后无法打包
2010-12-17 16:04 1630环境: MyEclipse Enterpr ... -
lucene入门
2010-11-17 16:20 858最近一直再研究lucene,把入门的程序和大家分享: 对 ... -
lucene 单机 io性能提高策略
2010-11-16 13:47 988蓝山咖啡(36668534) 13:30:35 所以,首先 ...
相关推荐
compass+ibatis+spring+struts2整合开发compass+ibatis+spring+struts2整合开发compass+ibatis+spring+struts2整合开发compass+ibatis+spring+struts2整合开发
标题“compass_hibernate_spring2.zip”提示我们这个压缩包可能包含了关于 Compass、Hibernate 和 Spring 三者结合使用的示例或教程。Compass 是一个全文搜索引擎,Hibernate 是一个流行的 Java ORM(对象关系映射)...
### 基于Compass2.2与Spring结合建立索引的实例 #### 一、Compass简介 Compass是一个开源的.NET和Java框架,它为应用程序提供了完整的文本搜索功能。该框架支持多种搜索引擎(如Elasticsearch, Solr等),使得开发...
标题“compass_hibernate_spring3.zip”提示我们这个压缩包可能包含了关于 Compass、Hibernate 和 Spring 3 框架的整合教程或者示例代码。Compass 是一个全文搜索引擎库,它为 Java 应用提供了类似 Google 的搜索...
总之,Compass、Hibernate和Spring的整合是一个强大且实用的解决方案,它让Java应用在处理大量数据时依然能保持良好的性能和响应速度。通过理解并掌握这种整合方式,开发者能够更好地应对复杂的企业级应用场景。
1. **ORM集成**:Compass可以与流行的ORM框架如Hibernate、JPA、iBatis等进行集成,自动将数据库中的对象创建成索引,无需手动处理索引的创建和维护。 2. **动态索引更新**:当数据库中的数据发生变化时,Compass...
### Compass入门指南:深入理解与实战应用 #### 核心概念解析 **1.1 Annotation vs. XML配置文件** 在Compass中,开发者可以选择使用Annotation或XML配置文件来进行配置。这两种方式各有优劣: - **Annotation...
标题 "整合compass2.0 spring hibernate示例源程序" 提供了我们即将探讨的核心内容,即一个结合了Compass 2.0、Spring和Hibernate的集成示例。这个项目旨在展示如何在Java应用程序中有效地利用这三个强大的开源框架...
Compass与Sass的结合,使得CSS代码更加模块化,更易于维护和扩展,同时引入了变量、嵌套规则、混合、函数等功能,让CSS编程变得更为强大。 二、Compass的安装 在开始使用Compass之前,你需要确保已经安装了Ruby环境...
在IT行业中,STRUTS、SPRING和HIBERNATE是三个非常重要的开源框架,它们分别专注于MVC(模型-视图-控制器)架构、依赖注入以及对象关系映射。而COMPASS则是一个基于Lucene的搜索引擎库,用于增强Java应用的全文检索...
总的来说,构建基于Compass和Spring的搜索引擎涉及理解Compass的核心概念,如OSEM、配置方式和API,以及如何利用Spring的集成优势简化开发流程。通过这种方式,开发者可以快速、高效地实现一个功能完备的全文搜索...
标题 "Spring ,JPA,Compass使用注解开发的博客站内搜索" 涉及的是在Java开发环境中,利用Spring框架、Java Persistence API (JPA) 和 Compass搜索引擎来实现一个博客系统的站内搜索功能。这是一项关键的技术,因为...
标题 "compass-2.2.0+hibernate-3.2+struts-2.1.8.1+spring-framework-2.5.4" 指的是一个集成开发环境,它结合了四个关键的技术组件:Compass、Hibernate、Struts 2 和 Spring Framework,这些都是Java Web开发中的...
Struts2、Spring、Hibernate和Compass是Java Web开发中常用的四大框架,它们各自负责不同的职责,协同工作可以构建高效、灵活的企业级应用。这里我们主要讨论如何将这些技术结合在一起,实现一个简单的搜索引擎功能...
Struts2、Hibernate、Spring 和 Compass 是Java Web开发中四个重要的框架和技术,它们共同构建了一个强大的企业级应用架构。在本项目中,开发者利用SSH2(即Struts2、Hibernate和Spring的组合)作为基础框架,并引入...
此项目对于理解Compass和Lucene在实际应用中的使用,以及如何结合SSH框架开发Java Web应用具有很高的学习价值。通过分析和研究这个项目,开发者可以深入掌握Java全文搜索引擎的实现,以及如何在SSH框架下组织和管理...
在Node.js学习过程中,MongoDB和Compass的结合使用可以帮助你更好地理解和操作数据库。通过Node.js的MongoDB驱动,你可以编写JavaScript代码来与MongoDB交互,创建和查询集合,执行CRUD(创建、读取、更新、删除)...
接着,他们可能会展示如何通过Spring的依赖注入来调用搜索服务,并使用Lucene和Compass提供的API来执行查询。最后,这个例子可能会涵盖如何优化搜索性能,以及如何处理索引和查询时可能出现的问题。 由于没有具体的...