最近参照springside
http://wiki.springside.org.cn/display/springside/Compass
重新开发了一下网站搜索功能.
引用
DataMirror会把数据库的增删改变化实时映射到索引文件中。
如果你采用Hibernate等ORM方案,Compass就会与Hibernate的event机制结合,或者使用AOP的方式,自动在数据库增删改时变更索引;如果你只是采用JDBC,也可以在XML文件配置Table Mapping或ResultSet Mapping,指定version列,Compasss定时对version列变化了的数据进行索引更新。
而且,Compass还支持事务,在查询数据库遍历结果集的过程中如果出现异常,会在Index Segments 文件一级进行事务控制。
如果没有Compass,我们一般会在每天深夜重建一次索引。相比Compass的做法,
一来反应迟缓,平均延时半天;
二来效率没有Compass高。如果采用完全重建索引,效率就不用说了。如果进行增量索引,就要增加一个字段,在数据更新时进行特殊的处理,删除时也不能直接删除数据,要等lucene删完索引数据才能删除,这样Lucene对应用就非常不透明了。
三来不支持事务,如果建立索引过程中出现异常,索引文件的状态是不可控的
---------------------------------------------------------------------
第一步,宣告待搜索的POJO!
一系列的annotation...我喜欢使用annotation
@Searchable
@SearchableId
@SearchableProperty
@SearchableComponent(refAlias="")
@Searchable(alias="article")
public class Article extends AbstractAutoID implements java.io.Serializable {
@SearchableComponent(refAlias = "column")
private ColumnModel column;
private String title;
@SearchableProperty
private String content;
private Integer hot;
private String author;
private Date loadtime;
private String srcfrom;
private Set<ArticleComment> comment;
getter/setter...
这一步有个注意点:关联的类,在写注解的时候,要写在属性上面,不要写在get方法上面..
不然搜索到的关联类为null.
而hibernate的关联注解要写get方法上,不然会报错...这是个区别...
事实不是像很多资料上写的,属性与方法上随便写...
第二步:Compass:核心定义类,定义要搜索的POJO 和 索引存储的路径。
CompassGPS: 定义使用了Hibernate3GPS,定义了init-method 和destory-method,会自动随ApplicaitonContext的启动,开始监控Hibernate的变化。
这个关键是配置文件了:
直接参考springside的就可以使用:
<bean id="compass" class="org.compass.spring.LocalCompassBean">
<!-- anontaition式设置 -->
<property name="classMappings">
<list>
<value>org.springside.bookstore.model.Book</value>
<value>org.springside.bookstore.model.Category</value>
</list>
</property>
<property name="compassConfiguration">
<bean class="org.compass.annotations.config.CompassAnnotationsConfiguration"/>
</property>
<property name="compassSettings">
<props>
<prop key="compass.engine.connection">
file://${user.home}/springside/compass
</prop>
<prop key="compass.transaction.factory">
org.compass.spring.transaction.SpringSyncTransactionFactory
</prop>
</props>
</property>
<property name="transactionManager" ref="transactionManager"/>
</bean>
<!-- Compass中建立索引与mirror database change的部件 -->
<bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps"
init-method="start" destroy-method="stop">
<property name="compass" ref="compass"/>
<property name="gpsDevices">
<list>
<bean class="org.compass.spring.device.hibernate.SpringHibernate3GpsDevice">
<property name="name" value="hibernateDevice"/>
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
</list>
</property>
</bean>
第三步:就是写搜索类...controller ,service..
重建索引的action..参考springside就可以了..
我使用的还是struts1.x..
public class RebuildSearchIndexAction extends Action {
private static final Logger log = Logger.getLogger(RebuildSearchIndexAction.class);
// 索引操作线程延时启动的时间,单位为秒
private int lazyTime = 10;
// Compass封装
private CompassGps compassGps;
public void setCompassGps(CompassGps compassGps) {
this.compassGps = compassGps;
}
// 索引线程
private Thread indexThread = new Thread() {
@Override
public void run() {
try {
Thread.sleep(lazyTime * 1000);
if(log.isInfoEnabled())
log.info("begin compass index...");
long beginTime = System.currentTimeMillis();
// 重建索引.
// 如果compass实体中定义的索引文件已存在,索引过程中会建立临时索引,
// 索引完成后再进行覆盖.
compassGps.index();
long costTime = System.currentTimeMillis() - beginTime;
if(log.isInfoEnabled())
log.info("compss index finished.");
if(log.isInfoEnabled())
log.info("costed " + costTime + " milliseconds");
} catch (InterruptedException e) {
// simply proceed
}
}
};
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
indexThread.setDaemon(true);
indexThread.setName("Compass Indexer");
indexThread.start();
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = null;
try {
out = response.getWriter();
}catch (Exception e){
}
out.print("compass indexer finish!!");
return null;
}
}
一条关键语句:
compassGps.index();
不再像过去,先删除旧的,再建新的.
搜索的controller
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
// TODO Auto-generated method stub
String query = StringUtil.encode(request.getParameter("query"),"utf-8");
Integer pageNo = IntegerUtil.parseInt(request.getParameter("pageNo"));
String type=request.getParameter("type");
// form get request,encode charactes
if (type==null){
type = "article";
}
AdvancedSearchCommand searchCommand = new AdvancedSearchCommand();
searchCommand.setQuery(query);
searchCommand.setHighlightFields(new String[] {"title"});
searchCommand.setPage(pageNo);
searchCommand.setAlias(type);
Page page = new Page(15);
SearchResults searchResults = new SearchResults(page);
searchResults.setQuery(query);
searchResults.setAlias(type);
searchResults.setCompassSearchResults(compassSearchService.search(searchCommand,page));
request.setAttribute("searchResults",searchResults);
/**
* 根据type类型,跳转到相应的页面.
* type = article | resource
*/
return mapping.findForward(type);
}
对于service,直接使用springside里的就可以.
但不太喜欢那个分页的效果,所以我重写了下..加了一个Page类..我现在分页都是使用taglib-pager组件..使用方便.
还改了一个地方:
/**
* 构建Lucene搜索器.
*/
protected CompassQuery buildQuery(CompassSearchCommand searchCommand,
CompassSession session) {
AdvancedSearchCommand ac = (AdvancedSearchCommand) searchCommand;
CompassBooleanQueryBuilder queryBuilder = session.queryBuilder().bool();
if (ac.getAlias() != null) {
queryBuilder.addMust(session.queryBuilder().alias(ac.getAlias()));
}
queryBuilder.addMust(session.queryBuilder().queryString(
ac.getQuery().trim()).toQuery());
这儿搜索加了个条件..搜索的alias..因为网站有文章外还有别的搜索源.....
效果可以到
http://www.java1995.cn上看看..只是现在还有一个乱码问题..
我使用的form method=get..自己也处理了字符编码..
但空间提供商,把server.xml中设置了URIEncode="GB2312"...我相当无语..
这个问题还在交涉....提供商的技术水平让人相当无语...
分享到:
相关推荐
SSH2和Compass整合构建搜索引擎是一个在Java Web开发中实现高效全文检索的常见技术实践。SSH2是指Spring、Struts2和Hibernate这三个开源框架的组合,它们分别负责控制层、表现层和持久层的处理。而Compass是一个基于...
标题 "整合compass2.0 spring hibernate示例源程序" 提供了我们即将探讨的核心内容:一个集成Compass 2.0、Spring和Hibernate的示例应用。这是一份源代码,旨在帮助开发者理解如何在实际项目中有效地将这三个关键...
本文将深入探讨如何将Compass与这三大框架整合,以实现高效、灵活的全站搜索功能。 一、Compass简介 Compass的核心功能是提供了一个简单易用的API,使得开发者能够方便地在数据库中的对象上添加全文索引。它支持...
Struts2、Spring、Hibernate和Compass是Java Web开发中常用的四大框架,它们各自负责不同的职责,协同工作可以构建高效、灵活的企业级应用。这里我们主要讨论如何将这些技术结合在一起,实现一个简单的搜索引擎功能...
通过以上步骤,我们可以将Compass与SSH框架成功整合,实现一个具备强大搜索功能的企业级应用。这不仅可以提高用户体验,也对后台数据管理带来便利,是现代Web开发中一项重要的技术实践。在实际项目中,开发者需要...
搜索方法可能接受关键词参数,然后使用Compass的QueryBuilder或直接写入Lucene的Query语法来构建查询。查询结果返回后,可以进一步封装为业务对象,以便在视图层展示。 在测试和优化阶段,可能会涉及性能调优,如...
3. Compass Spring:整合Spring框架,便于在Spring应用中使用Compass。 Compass中的重要概念: - Compass相当于Hibernate的SessionFactory,负责创建和管理索引。 - CompassSession类似Hibernate的Session,管理...
在本项目中,"JAVA 全文搜索 struts2+spring+hibernate+compass整合记录" 是一个关于如何在Java环境下集成四个关键组件来实现全文搜索引擎的实践教程。Struts2是一个流行的MVC框架,Spring是核心的依赖注入框架,...
这个实例提供了从零开始使用Compass进行全文检索的一个起点,通过它你可以快速地了解和实践Compass的使用,同时也可以学习如何在SSH框架下整合全文检索功能。在深入学习和实践中,你将进一步掌握如何利用Compass提升...
通过研究这个SSH2+Compass2.2搜索实例,开发者可以学习到如何在J2EE应用中整合多个框架以实现复杂的功能,如搜索引擎集成。此外,还会了解如何使用MyEclipse这样的IDE进行开发,以及如何管理和部署SQL数据库。这是一...
5. 如何在Java Web应用中整合这些技术实现站内搜索 6. 可能涉及的源码解析和示例 7. 应用部署和运行所需的库文件管理 如果想深入了解这些知识点,可以参考博文链接提供的内容,或者查阅相关框架和Compass的官方文档...
Compass 是一个基于 Lucene 的搜索引擎库,为 Java 应用提供了简单易用的全文搜索功能。它允许开发者将元数据(如注解)与类关联,以便在数据库中进行高效的全文检索。Compass 提供了对 ORM 框架(如 Hibernate)的...
### Compass入门指南:深入理解与实战应用 #### 核心概念解析 **1.1 Annotation vs.... 在Compass中,开发者可以选择使用Annotation或XML...对于开发者而言,掌握Compass的核心概念和API是构建高性能搜索应用的关键。
- **简单的API**:提供了一组易于使用的API,便于开发者快速构建搜索应用。 - **可扩展与模块化框架**:允许用户根据需要扩展框架的功能。 - **事务管理**:支持事务性的操作,确保数据的一致性和完整性。 #### ...
5. **Spring 整合 Compass**:Spring 提供了 Compass 的支持,允许开发者在 Spring 应用中透明地集成全文搜索功能。这包括自动配置 Compass Session,以及将 Compass 操作与 Spring 事务进行协调。 6. **配置与集成...
接下来,我们将深入探讨如何在项目中整合Compass、Hibernate和Spring。 Compass是一个基于Lucene的全文搜索引擎,它为Java应用程序提供了一种简单的方式来实现对数据的快速检索。Compass通过元数据映射机制,可以将...
综上所述,巴巴运动包是一个整合了Compass和Lucene的Java应用,旨在提供搜索功能。Compass作为一个基于Lucene的框架,简化了在Java应用中集成搜索引擎的过程,而Lucene则提供了强大的文本搜索能力。通过解压并导入这...
总结起来,这个项目是使用Spring、Hibernate、Struts2和Compass2.1构建的一个企业级Web应用,具备强大的后端数据管理、ORM、MVC架构以及高效的全文搜索功能。通过合理配置和整合这些技术,开发者可以创建出功能完备...
Compass 作为一款高级的搜索引擎框架,通过对其核心组件的深入了解,我们可以更好地利用其提供的强大功能来构建高效、灵活的搜索解决方案。无论是对于初学者还是有经验的开发者而言,掌握这些核心概念都是非常重要的...