整合compass构建搜索
最近参照springside
http://wiki.springside.org.cn/display/springside/Compass
重新开发了一下网站搜索功能.
@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" ref="transactionManager"/></bean><!-- Compass中建立索引与mirror database change的部件 --><bean id="compassGps" destroy-method="stop"><property name="compass" ref="compass"/><property name="gpsDevices"><list><bean 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() {@Overridepublic 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 stubString query = StringUtil.encode(request.getParameter("query"),"utf-8");Integer pageNo = IntegerUtil.parseInt(request.getParameter("pageNo"));String type=request.getParameter("type");// form get request,encode charactesif (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"...我相当无语..
这个问题还在交涉....提供商的技术水平让人相当无语... 1 楼 flyfan 2008-12-15 不错,我也想用Compass重新开发了一下网站搜索功能.学习一下了,谢谢